我有一组数字说:
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,并且您已经在左侧看到了x
1s。根据上述分析,这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);
}