每日算法【数组】 - 移动零

79 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

好好学习,天天刷题~~

今日份刷题【移动零记录如下:

题目描述

给定一个数组 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

暴力破解法

暴力破解思路及其简单:定义循环的个数k等于数组的长度,遍历数组,如遇到当前为零,则将零移除掉,并在某位补零,同时将k减去1。这样就可简单实现移动零。但是这样暴力破解很不推荐。 具体代码如下:

var moveZeroes = function(nums) {
var i=0;
var k = nums.length;
while(i<k){
   if(nums[i]==0){
    nums.splice(i,1);
    nums.push(0);
    k--;
   }else{
    i++;
   }
   
}
return nums;
};

不出意外,结果就是这么的。。。。

image.png

双指针法(两次遍历)

  • 定义两个指针,一个为b为右指针,一个为i左指针。
  • 第一次遍历,右指针b用来记录当前有多少不为零的个数,也就是在遍历的时候一旦遇到非零的元素就将其往数组左边挪,即非零的元素统统赋值给nums[b]。
  • 第二次遍历,将末尾剩下的元素置为零。 具体代码如下:
var moveZeroes = function(nums) {
let b=0;
for(let i=0;i<nums.length;i++){
   if(nums[i]!=0){
     nums[b++] = nums[i];
   }
}
for(var j=b;j<nums.length;j++){
  nums[j]=0;
}
return nums;
};

提交结果如下:

image.png

双指针法(一次遍历)

这里最后提供一个一次遍历的思路,其实和上一个方法思路类似。只不过是左值针不断向右移,当遇到非零元素,则左右指针对应的数交换即可。这样一次遍历就可以搞定。