给定一个数组 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
方法1:使用删除0的方式解决
这是一个非官方推荐的解决方式,因为这道题考察的是双指针的知识点,可以作为一个思考方向
- 遍历数组:
- 从数组末尾向前遍历,找到所有的 0 并移除它们,同时增加
zeroTotalNum
。
- 从数组末尾向前遍历,找到所有的 0 并移除它们,同时增加
- 调整数组长度:
- 根据
zeroTotalNum
增加数组的长度。 - 在数组末尾填充相应数量的 0。
- 根据
<script>
var moveZeroes = function (nums) {
let startIndex = 0;
let endIndex = 0;
let zeroTotalNum = 0;
let originLen = nums.length;
for(let index = originLen - 1;index>=0;index--){
if(nums[index] === 0){
zeroTotalNum++;
nums.splice(index,1)
}
}
nums.length+=zeroTotalNum;
nums.fill(0,nums.length - zeroTotalNum);
return nums;
};
console.log(moveZeroes([0,1,0,3,12]));
</script>
核心思想是先将0的位置记录出来,删除0后,再在数组尾部增加等量的0.
方法2:使用双指针方式解决。
- 第一次遍历:
- 遍历数组时,如果
nums[i]
是非零元素,则将nums[i]
赋值给nums[j]
,然后j
自增。 - 这样做的结果是,所有非零元素按原顺序排列在数组的前面部分。
- 遍历数组时,如果
- 第二次遍历:
- 从
j
开始到数组结束,将所有位置置为 0。
- 从
var moveZeroes = function (nums) {
let j = 0;
for(let i=0;i<nums.length;i++){
if(nums[i]!==0){
nums[j] = nums[i]
j++
}
}
nums.fill(0,j)
return nums;
};
总结
虽然两种方法都可以实现将 0 移动到数组末尾,但双指针方法更高效,因为它在一次遍历中完成元素的移动,避免了使用 splice
导致的多次数组重组。推荐使用双指针方法。