题目

题目解读
1.只能原地对数组进行操作,保持非零元素的原有顺序
2.就是把零移动到末尾
开始解题
一、覆盖 + 补零
思路:
想象我们有一个"慢指针" slow,它始终指向"下一个非零元素应该填入的位置"。
另一个"快指针" fast 遍历整个数组:
如果 nums[fast] 不是 0,就把它覆盖到 slow 的位置,然后 slow 右移一位。
如果 nums[fast] 是 0,就跳过。
遍历结束后,slow 左边的所有位置都是非零元素,且相对顺序不变。此时 slow 及其之后的位置都应该变成 0,只需用另一个循环填充即可。
核心流程:
1.初始化 slow = 0。
2.用 fast 遍历数组:
如果 numsfast != 0:执行 numsslow = numsfast,slow++。
3.遍历完成后,用 for (i = slow; i < nums.length; i++) 将剩余位置全部置为 0。
代码
java
public void moveZeroes(int[] nums) {
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != 0) {
nums[slow] = nums[fast];
slow++;
}
}
// 将 slow 到末尾全部填 0
for (int i = slow; i < nums.length; i++) {
nums[i] = 0;
}
}
二、交换法
思路:
方法一在覆盖时,fast 位置的原值被残留下来,最后需要额外补零。
我们可以改用交换 的思路:当 fast 遇到非零元素时,让它与 slow 位置的元素交换。
由于 slow 位置上的元素要么是 0,要么就是已经被处理过的非零元素 (如果数组前面没有 0,slow 和 fast 会同步前进,交换不会产生负面影响)。
这样,零会被一步步"推"到数组末尾,无需最后的补零循环,每个元素至多参与一次交换,操作次数更少。
核心流程:
1.初始化 slow = 0。
2.用 fast 遍历数组:
如果 numsfast != 0:
交换 numsslow 和 numsfast。
slow++。
3.遍历结束后,数组已经满足要求,无需额外操作。
代码
java
public void moveZeroes(int[] nums) {
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != 0) {
// 交换 nums[slow] 和 nums[fast]
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
slow++;
}
}
}
感谢您能够看到这里,一起见证小何同学的算法学习,如果您有不同的见解,希望能得到您的指点和点悟;如果您是和我一样的同学,也希望这篇文章能对您有所帮助。