双指针算法介绍及使用(上)

1. 算法简介

双指针算法是一种通过使用两个指针(或索引)在数据结构(如数组、链表)中协同遍历来解决问题的技术。通常用于优化时间复杂度,将O(n²)降低到O(n)或O(nlogn)。

2. 常见类型

一般来说,双指针有两种形式,⼀种是对撞(左右)指针,⼀种是快慢指针。

2.1 对撞指针

这种简单来说就是在数组的左右两边各自加上一个指针,然后控制他们从两端向中间移动。比如我们所知道的快速排序,它从代码结构上来说体现了这一点。

2.2 快慢指针

它的核心思路是,使用两个指针(快指针和慢指针),这两个指针在遍历数据结构时速度不同。借助这种速度差,能解决诸如寻找链表中间节点、判断链表是否存在环等问题。

3. 实际使用

3.1 leetcode 283. 移动零

这道题就是一个快慢指针的实际使用场景,在数组的0和1的位置分别放上慢指针和快指针,

然后分场景判断来实现题目要求。

接下来是其代码实现:

先设置快慢指针fast和slow,然后分条件判断,以下就是判断的条件,然后将表格中的内容写成代码就可以了。

|------|--------|---------------|---------------|--------------------|
| fast | ==0 | ==0 | !=0 | !=0 |
| slow | ==0 | !=0 | !=0 | ==0 |
| | fast++ | slow++,fast++ | slow++,fast++ | swep,slow++,fast++ |

cpp 复制代码
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int fast=1;
        int slow=0;
        while(fast<=nums.size()-1)
        {
            if(nums[slow]==0&&nums[fast]!=0)
            {
                swap(nums[slow],nums[fast]);
                slow++;
                fast++;
            }
            else if(nums[slow]==0)
            {
                fast++;
            }
            else
            {
                fast++;
                slow++;
            }
        }
    
    }
};

3.2 leetcode 1089. 复写零

这道题的话难度稍微有一点点高,要使用两次双指针。看题可知,我们要从后往前来遍历(从前往后会覆盖数据),我们先第一次遍历来找到修改完后的最后一位数,然后从后往前遍历即可。

PS:if(end>=n-1)这里不可以写成if(end>n),原因是**边界条件的判断逻辑不同。**后者会多判断一次,因为当end在最后一位数的时候end>n的条件还没有满足。简单来说刚刚越界的时候会进入这个判断。

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int end=-1;
        int cur=0;
        int n=arr.size();
        while(cur<n)
        {
            if(arr[cur])
                end++;
            else
                end+=2;
            if(end>=n-1)
                break;
            cur++;
        }
        if(end==n)
        {
            end--;
            arr[end--]=0;
            cur--;
        }
        while(cur>=0)
        {
            if(arr[cur]!=0)
            {
                arr[end]=arr[cur];
                cur--;
                end--;
            }
            else
            {
                cur--;
                arr[end--]=0;
                arr[end--]=0;
            }
        }
    }
};
相关推荐
千金裘换酒36 分钟前
LeetCode 二叉树的最大深度 递归+层序遍历
算法·leetcode·职场和发展
爱敲代码的TOM37 分钟前
详解一致性哈希算法
算法·哈希算法
lzllzz2344 分钟前
递归的理解
算法·深度优先·图论
小O的算法实验室1 小时前
2024年IEEE TITS SCI2区TOP,考虑无人机能耗与时间窗的卡车–无人机协同路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
派森先生1 小时前
排序算法-选择排序
算法·排序算法
C雨后彩虹1 小时前
书籍叠放问题
java·数据结构·算法·华为·面试
ghie90901 小时前
GPS抗干扰算法MATLAB实现
开发语言·算法·matlab
格林威1 小时前
基于轮廓特征的工件分类识别:实现无模板快速分拣的 8 个核心算法,附 OpenCV+Halcon 实战代码!
人工智能·数码相机·opencv·算法·目标跟踪·分类·数据挖掘
Jasmine_llq1 小时前
《UVA11181 条件概率 Probability|Given》
数据结构·算法·深度优先搜索(dfs)·剪枝(可行性剪枝)·组合枚举(递归暴力枚举)·条件概率统计与归一化
老鼠只爱大米1 小时前
LeetCode算法题详解 560:和为K的子数组
算法·leetcode·前缀和·哈希表·子数组求和·subarraysum