题目分析
- 不能考虑遇到0直接和数组末尾交换,这样会破环相对顺序
- 反过来想,把0移动到数组末 == 把非0移动到前面
- 一趟扫描,遇到0就跳过,遇到非0就把它挪到前面去
- cur记录着可以挪动到的位置
注意当nums[i] != 0
,且cur
和i
指向同位置,即非0数看作已经放好位置了
Solution
public void moveZeroes(int[] nums) {
if (nums == null) return;
for (int i = 0, cur = 0; i < nums.length; i++) {
if (nums[i] == 0) continue;
if (cur != i) {
nums[cur] = nums[i];
nums[i] = 0;
}
cur++;
}
}
题目变式-PolishFlag
Given an array A[1…N] with elements Red and White, rearrange the order by swapping alone so that all Whites come before all Reds
def polishflag(flag):
# Precondition: flag is a list containing only 0’s and 1’s
n = len(flag)
i, j = 0, 1
while (j < n):
# Loop invariant: no indices below i are 0’s,
# no indices between i+1 and j-1 are 1’s
while (i < n) and flag[i] == 1:
i += 1
j = i+1
while (j < n) and flag[j] == 0:
j += 1
if (j < n):
flag[i], flag[j] = flag[j], flag[i]
return flag
# Postcondition: i = number of 1’s
# no indices below i are 0’s,
# no indices between i+1 and n-1 are 1’s
Reference:小码哥MJ