题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
解题思路
目标是将数组中的所有 0 移动到数组的末尾,同时保持非零元素的相对顺序不变。
选择使用合适的策略(双指针法):使用两个指针来遍历数组,一个指针用于遍历整个数组,另一个指针用于记录非零元素应该放置的位置。
步骤解析
-
初始化一个变量
a. 变量lastNonZeroIndex
,来跟踪最后一个非0元素的位置 -
遍历数组,
a. 使用一个循环遍历数组中的每个元素。
b. 当遇到非0元素时,将其赋值给nums[lastNonZeroIndex]
,并将lastNonZeroIndex
向前移动1位 -
填充 0
a. 在结束遍历后,使用另一个循环,从lastNonZeroIndex
的位置到数组末尾填充0。
时间和空间复杂度
- 时间复杂度:O(n),因为数组只被遍历了一次。
- 空间复杂度:O(1),只使用了常数级别的额外空间。
代码实现
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
function moveZeroes(nums) {
// 1. 初始化一个变量 lastNonZeroIndex ,来跟踪最后一个非零元素的位置
let lastNonZeroIndex = 0;
// 2. 遍历数组,使用一个循环遍历数组中的每个元素。
// 当遇到非零元素时,将其赋值给 nums[lastNonZeroIndex] ,并将 lastNonZeroIndex 向前移动一位
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== 0) {
nums[lastNonZeroIndex] = nums[i];
lastNonZeroIndex++;
}
}
// 3. 填充 0
// 在结束遍历后,使用另一个循环,从 lastNonZeroIndex 的位置到数组末尾填充零。
for (let i = lastNonZeroIndex; i < nums.length; i++) {
nums[i] = 0;
}
return nums;
}
// 示例用法
const nums = [0, 1, 0, 3, 12];
moveZeroes(nums);
console.log(nums); // 输出: [1, 3, 12, 0, 0]