Hot-Leecode 1:移动零(283)

今天起开一个小白刷算法专栏,可能复杂度不是最高的,但是首先要保证自己能做出来,帮助自己对代码和算法要熟悉,也将自己的思路给想学好代码的人提供。

双指针——移动零(283)

栈做:

这题我想到的用栈做,首先写出下面这段代码

import java.util.Stack;

class Solution2 {
    //nums = [0,1,0,3,12],输出:[1,3,12,0,0]
    //这个我想到了用栈去做,不是0就入栈,是0就最后入栈,补0
    public void moveZeroes(int[] nums) {
        Stack<Integer> stack=new Stack<>();
        //补0,就得统计0的个数
        int CountZeros=0;
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]!=0){
                stack.push(nums[i]);
            }else {
                CountZeros++;
            }
        }
        //现在就要还原这个数组,把栈里的元素按顺序弹出来
        //但是栈它是后进先出啊
        int index=0;
        while (!stack.isEmpty()){
            nums[index]=stack.pop();
            index++;
        }
        //补0,补几个0就是补CountZeros的个数
        //上面就是走到nums[index]了,几个CountZeros,补几个0
        for (int i = 0; i < CountZeros; i++) {
            nums[index]=0;
            index++;
        }
    }
}

思路讲解:

1.首先我想到了用栈去做,不是0就入栈,是0就最后入栈,补0

2.既然要补0,就得统计0的个数

3.当非0的入到栈里了,现在就要还原这个数组,把栈里的元素按顺序弹出来

4.但是实际运行时候发现报错了,栈的话是后进先出,比如stack.pop()先弹出来的是后面的12,3,1;再补0 [12,3,1,0,0]

5.所以用栈没法做出来

数组:

再来一个数组做:栈不行,我就用新数组按顺序做,这次成功了

class Solution2 {
    //nums = [0,1,0,3,12],输出:[1,3,12,0,0]
    //这个我想到了用栈去做,不是0就入栈,是0就最后入栈,补0
    //现在完善一下,用新数组去做
    public void moveZeroes(int[] nums) {
        int[] nums2=new int[nums.length];
        //nums[i]遍历一遍,非0的数就按顺序放到新nums2[]里面
        //记录非0的个数
        int nonCountZeros=0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i]!=0){
                nums2[nonCountZeros]=nums[i];
                //这个nonCountZeros++必须在if里面,只有这样nums2[nonCountZeros]才会自增,新数组才会有值,否则所有不为0的值都会覆盖到nums2[0]的位置
                nonCountZeros++;
            }
        }
        //后面补0
        for (int i = nonCountZeros; i < nums.length; i++) {
            nums2[i]=0;
        }
        //新数组返还给原数组
        for (int i = 0; i < nums.length; i++) {
            nums[i]=nums2[i];
        }
    }
}

思路讲解:

1.现在完善一下,用新数组去做

2.nums[i]遍历一遍,非0的数就按顺序放到新nums2[]里面

3.记录非0的个数,后面补0

4.新数组返还给原数组。

双指针

这回看一个正规做法,其实和上面那个数组差不多,只不过它不用数组了

class Solution {
    //正规双指针
    public void moveZeroes(int[] nums) {
       int nonCountZeros=0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i]!=0) {
                nums[nonCountZeros] = nums[i];
                nonCountZeros++;
            }
        }
        //填充后面的位置
        for (int i = nonCountZeros; i < nums.length; i++) {
            nums[i]=0;
        }

    }
}

思路讲解:

1.其实和数组很像,但是这里不需要引入数组

2.当非0的数确认了,后面的数变为0即可

注意:

有一个问题我要理清一下, for (int i = nonCountZeros; i < nums.length; i++) 第二个循环不是从nonCountZeros+1开始,就是从nonCountZeros开始。因为nonCountZeros的值表示了非零元素的个数,所以它指向了后一个元素

  • 初始状态:[0, 1, 0, 3, 12]nonCountZeros=0
  • 遍历到元素1:由于1不为零,将其移到位置0,nonCountZeros加一变为1。数组变为:[1, 1, 0, 3, 12]nonCountZeros=1
  • 遍历到元素0:由于0为零,跳过不处理,数组保持不变。
  • 遍历到元素3:由于3不为零,将其移到位置1,nonCountZeros加一变为2。数组变为:[1, 3, 0, 3, 12]nonCountZeros=2
  • 遍历到元素12:由于12不为零,将其移到位置2,nonCountZeros加一变为3。数组变为:[1, 3, 12, 3, 12]nonCountZeros=3

完成第一个循环后,数组的前三个位置 [1, 3, 12] 已经被移动成了非零元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值