我有一组数字说:

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。
假设你的目标是最左边的1。你看到的从左到右的第一个1显然是你在第一个位置想要的1(所有其他的1只需要更多的交换就可以到达第一个位置)。事实上,你看到的每一个1都属于你已经看到的1之后的下一个位置。
如果您的目标是最左边的0,则0也是如此。
这需要多少步骤?很简单。假设您在位置i处看到1,并且您已经在左侧看到了x1s。根据上述分析,这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);
}

10-05 21:24