给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
**进阶:**你能尽量减少完成的操作次数吗?
方法思路 要将所有零移动到数组末尾,同时保持非零元素的相对顺序,可以采用双指针法。通过两次遍历实现:
- 第一次遍历:使用快慢指针,快指针遍历数组,遇到非零元素时,将其移动到慢指针的位置, 并移动慢指针。这样所有非零元素会被移动到数组前面。
- 第二次遍历:将慢指针之后的所有位置填充为零,以确保零元素位于数组末尾。
这种方法保证了时间复杂度为 O(n),且原地操作,无需额外空间。
解决代码
var moveZeroes = function(nums) {
let left = 0;
// 将非零元素移到前面
for (let right = 0; right < nums.length; right++) {
if (nums[right] !== 0) {
nums[left] = nums[right];
left++;
}
}
// 将剩余位置填充零
for (let i = left; i < nums.length; i++) {
nums[i] = 0;
}
};
代码解释
- 第一次遍历:快指针
right
遍历数组,当遇到非零元素时,将其赋值给慢指针left
的位置,并递增left
。这样遍历结束后,所有非零元素都被移动到数组的前面。 - 第二次遍历:从慢指针
left
的位置开始,将剩余的位置填充为零,确保所有零元素位于数组末尾。该方法保证了非零元素的相对顺序不变,且原地操作。