模块一:双指针——283.移动零

双指针

常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是快慢指针

对撞指针

  • ⼀般⽤于顺序结构中,也称左右指针。
  • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼
    近。
  • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循
    环),也就是:
left == right (两个指针指向同⼀个位置)
left > right (两个指针错开)

快慢指针

  • ⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。
  • 这种⽅法对于处理环形链表或数组⾮常有⽤。
  • 如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。
  • 快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

题目解析

题目链接:283.移动零在这里插入图片描述
题目很简单,就是把数组中的所有为0的元素移动数组末尾,且只能在原数组上操作还得保证非0元素的相对顺序。(ps:可以根据示例理解题目)

算法原理

这道题其实可以归类到一类题里面——数组划分(数组分块),这不是官方的名字,是本人总结出来的。
在这里插入图片描述
这是以上说的一类题的特点,而本题中,则将一个数组划分为两块区间。
在这里插入图片描述
解决这类问题,我们第一个想到的就是双指针算法,在数组中,我们通常用数组下标来充当指针使用。
在这里插入图片描述
根据我们的分析来举一个示例
在这里插入图片描述
因为刚开始的时候数组还未处理,所以让dest指向-1
在这里插入图片描述
当nums[cur]==0时不处理,cur++,当遇到非零元素时,++dest,再交换nums[cur]和nums[dest],最后让cur++,重复以上步骤,直到cur走到n的位置。这样就保证了[0,dest]非0,[dest+1,cur-1]为0,[cur+1,n-1]为待处理区间,符合我们的性质。

代码编写

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int cur = 0;//把数组分为两个部分,处理部分[nums[0],nums[cur-1]]和非处理部分[nums[cur],nums[nums.size()-1]]
        int dest = -1;//把处理部分分为两个部分,[nums[0],nums[dest]]为非零元素,[nums[dest+1],nums[-1]]为零元素
        for(;cur < nums.size();cur++)
        {
            //因为只遍历一遍所以时间复杂度为O(n),只定义了两个变量所有空间复杂度为O(1)
            if(nums[cur])
            {
               swap(nums[++dest],nums[cur]);
            }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全天

加油,大佬们!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值