将1和0一起排列在一个数组中

时间:2019-01-05 18:42:44

标签: java algorithm

我有一组数字说:

1, 0, 1, 0, 0, 0, 0, 1

现在使用最小移动量,我希望将1和0分组,条件是一个数字只能与它的相邻位置向左或向右交换。

1, 0, 1, 0, 0, 0, 0, 1 -->     1, 1, 0, 0, 0, 0, 0, 1 -->     
1, 1, 0, 0, 0, 0, 1, 0 --> 1, 1, 0, 0, 0, 1, 0, 0 --> 
1, 1, 0, 0, 1, 0, 0, 0 --> 1, 1, 0, 1, 0, 0, 0, 0 --> 
1, 1, 1, 0, 0, 0, 0, 0

这里花了6步,所以程序应该返回6。

这是我的程序:

public static int arrange(List<Integer> nums) {
    int n = nums.size();
    boolean modified = false;
    int first = nums.get(0);
    int index = -1;
    int count = 0;
    for (int i = 1; i < n; i++) {
        if (first != nums.get(i)) {
            index = index == -1 ? i : index;
            modified = true;
        }
        if (modified) {
            if(first == nums.get(i)) {
                count += i - index;
            }
        }
    }
    if (count == 0) {
        return 0;
    } else {
        return count - 1;
    }
}

对于某些输入,该程序看起来不错。但是我在这里缺少条件,我从位置0到输入的大小,没有考虑所有可能的条件,例如反向操作或中途更改顺序等。

您能帮我介绍一下这里的正确方法吗?

1 个答案:

答案 0 :(得分:7)

请注意,最终位置有两种可能性。最左边的元素是1或0。

假设您的目标是最左边的1。从左到右看到的第一个1显然是您想要的第一个位置(其他所有对象将需要更多的交换才能到达第一个位置)。实际上,您看到的每个1都会在您已经看到的1以后属于下一个位置。

如果您的目标是最左边的0,则对于0也是如此。

需要多少步骤?简单。假设您在位置i看到1,并且已经在左边看到x 1。根据上面的分析,此1在最终位置的索引将为x。步骤数= i - x

这是一个简单的实现:

public static int arrange(List<Integer> nums) {
    int n = nums.size();
    int seen1s = 0;
    int seen0s = 0;
    int steps_left1 = 0;
    int steps_left0 = 0;

    for (int i = 0; i < n; i++) {
        if (nums.get(i) == 1) {
            steps_left1 += i - seen1s;
            seen1s += 1;
        } else {
            steps_left0 += i - seen0s;
            seen0s += 1;
        }
    }
    return Math.min(steps_left1, steps_left0);
}