【双指针】:Leetcode283.移动零

简介: 【双指针】:Leetcode283.移动零

1. 双指针思想

常见的双指针有两种形式:一种是对撞指针、一种是快慢指针

1. 对撞指针:一般位于顺序结构中,也被称为左右指针。

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

               (两个指针相撞)

               (两个指针错开)

2. 快慢指针:⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。

  • 这种⽅法对于处理环形链表或数组以及循环往复的问题⾮常有⽤。
  • 快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:
  • 在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

2. 移动零

Leetcode283.移动零:https://leetcode.cn/problems/move-zeroes/

题目描述:

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]输出:[1,3,12,0,0]

示例 2:

输入: nums = [0]输出:[0]

2.1 题目解析

根据题目描述,通过区间的划分对数组进行操作,可以简单的理解为将整个数组划分为两块,「数组分两块」是⾮常常⻅的⼀种题型,主要就是根据⼀种划分⽅式,将数组的内容分成左右两部分。这种类型的题,⼀般就是使⽤「双指针」来解决。

2.2 算法思路

解决本题使用的是双指针算法:

在这里为了方便,可以直接使用数组的下标来进行指针的模拟,要想对数组进行分块,首先设置一个指针(cur)对数组进行遍历,要将非0放到左边还需要一个指针(dest)来对数组进行区域划分,那么这两个指针的作用分别是:

cur:从左向右扫描,遍历整个数组。

dest:已处理区间内,非0元素的最后一个位置。

在遍历的整个过程中这两个指针会将数组分为三个区间:

如何实现呢?

首先让cur和dest都指向数组的起始位置(或者让dest指向-1的位置),然后让cur指针向后遍历,这时cur指针会遇到两种情况:

1. 遇到0时,直接++cur,继续向后面走。

2. 遇到非0时,需要交换dest位置与cur位置的元素,然后再将dest和cur加1。

结束的条件cur遍历完整个数组。

2.3 代码实现

使用最简单的循环语句即可完成遍历和判断:

class Solution 
{
public:
    void moveZeroes(vector<int>& nums) 
    {
        int cur = 0, dest = 0;
        for(;cur < nums.size(); cur++)
        {
            if(nums[cur])  //非0再交换
                swap(nums[dest++], nums[cur]);  //后置++,使用完了再++进行迭代
            //为0就继续向后面迭代
        }
    }
};

2.4 算法复杂度

该算法遍历一遍数组即可,时间复杂度:0(N)

没有开辟额空间,空间复杂度:O(1)

算法小总结:

数组分块,区间划分是在快速排序算法 中也有提到的,快速排序算法的关键就是进行区间的划分。

朋友们、伙计们,美好的时光总是短暂的,我们本期算法的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!  

目录
相关文章
|
3月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
22 1
|
5月前
|
索引
力扣每日一题 6/17 枚举+双指针
力扣每日一题 6/17 枚举+双指针
33 1
|
5月前
|
存储 算法 数据可视化
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
|
5月前
|
算法 数据挖掘 Java
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
|
5月前
|
存储 算法 数据挖掘
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
|
5月前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
|
6月前
|
算法
[优选算法]——双指针——Leetcode——1089. 复写零
[优选算法]——双指针——Leetcode——1089. 复写零
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
5月前
|
算法 容器
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和