当前位置: 首页 > article >正文

双指针优质算法题集

目录

一、双指针算法介绍

二、移动0

1、题目链接

2、题解

3、代码实现

(1)、初次实现:

(2)、优化后的实现:

二、复写0

1、题目链接:

2、题解

3、代码实现


一、双指针算法介绍

这里的指针不是真的指针,是数组下标

常见两种双指针形式:

(1)、对撞指针:从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。对撞指针的终⽌条件⼀般是两个指针相遇或者错开。

(2)、快慢指针:⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。这种⽅法对于处理环形链表或数组⾮常有⽤

快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:

在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

二、移动0

1、题目链接

283. 移动零 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/move-zeroes/description/

2、题解

这类题通常被称为数组划分或者数组分块,如下:

分析:

(1)、两个指针dest和cur的作用:

cur:从左向右扫描数据,遍历数组;

dest:指向已处理的区间内,非零元素的最后一个位置;

(2)、三个区间:[0,dest]  [dest+1,cur-1]   [cur,n-1]

(3)、如何做到:

       

3、代码实现

(1)、初次实现:

         

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int cur = 0;
        int dest = -1;
        while(cur<nums.size())
        {
            if(nums[cur] != 0)
            {
                dest++;
                swap(nums[dest],nums[cur]);
            }
            cur++;
        }
    }
};

(2)、优化后的实现:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        for(int cur = 0,dest = -1;cur<nums.size();cur++)
        {
            if(nums[cur] != 0)
            {
                swap(nums[++dest],nums[cur]);
            }
        }
    }
};

二、复写0

1、题目链接:

https://leetcode.cn/problems/duplicate-zeros/description/icon-default.png?t=O83Ahttps://leetcode.cn/problems/duplicate-zeros/description/

2、题解

该题可使用双指针解法:

先根据“异地操作”,即开辟一个新数组,两个数组上进行分析,然后优化成双指针下的“就地”操作。然后一定要多画图分析再进行写代码。

具体步骤可分为三步:先找到最后一个复写的数、处理边界情况、从后往前完成复写操作。

(1)、先找到最后一个复写的数:

该步骤也需要用双指针,指针cur起始值为0,指针dest起始值为-1,然后开始循环比较,如果cur指向的值等于0,则dest += 2,即向后走两步,反之如果不等于0,则dest++,即向后走一步。当dest走完原数组时,cur刚好指向最后一个需要复写的数。

 //找最后一个复写的数
       int dest = -1,cur = 0;
       int n = arr.size();
       while(cur < n)
       {
            if(arr[cur] == 0)
            {
                dest += 2;
            }
            else
            {
                dest++;
            }
            if(dest >= n - 1)break;
            cur++;
       }   

(2)、处理边界情况:

在(1)的算法下有个漏洞,即若dest指针走到数组的倒数第二个数时,并且最后一个复写的数为0,那么dest向后走两步就会越界,此时需要进行单独处理,先将最后一个数写为0,然后将dest定位到cur位置,在进行第三步。

//处理边界情况,若进入,提前处理最后一个复写的数
       if(dest == n)
       {
            dest--;
            arr[dest--] = 0;
            cur--;
       }

(3)、从后往前完成复写操作:

前两步完成后就进入一个循环,然后判断cur处的值:若为0,则dest从后往前将两个位置写成0;若不为0,则dest从后往前复写一个位置的数。

 //从后往前进行复写
       while(cur >= 0)
       {
            if(arr[cur] == 0)
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
            else
            {
                arr[dest] = arr[cur];
                dest--;
                cur--;
            }
       }

3、代码实现

 void duplicateZeros(vector<int>& arr) {
        //找最后一个复写的数
       int dest = -1,cur = 0;
       int n = arr.size();
       while(cur < n)
       {
            if(arr[cur] == 0)
            {
                dest += 2;
            }
            else
            {
                dest++;
            }
            if(dest >= n - 1)break;
            cur++;
       }   
       //处理边界情况,若进入,提前处理最后一个复写的数
       if(dest == n)
       {
            dest--;
            arr[dest--] = 0;
            cur--;
       }
       //从后往前进行复写
       while(cur >= 0)
       {
            if(arr[cur] == 0)
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
            else
            {
                arr[dest] = arr[cur];
                dest--;
                cur--;
            }
       }
    }


http://www.kler.cn/a/395862.html

相关文章:

  • 跟我学C++中级篇——Design Patterns的通俗说法
  • 什么是项目完整性管理?
  • centos rich 美观打印日志
  • 《动手学深度学习》中d2l库的安装以及问题解决
  • 【大模型实战篇】vLLM的由来以及大模型部署、推理加速实践
  • 阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_作战无人机和察打无人机图鉴
  • 基于STM32的智能语音识别饮水机系统设计
  • Ajax异步调用
  • css 溢出隐藏显示省略号
  • 地质旅游平台推动“旅游+地质”融合发展
  • Spring学习笔记_34——@Controller
  • 协方差矩阵及其计算方法
  • 动态规划 之 子数组 算法专题
  • Ceph 中PG与PGP的概述
  • Algen的跨链互操作性:增强区块链连接性
  • CSS Module:告别类名冲突,拥抱模块化样式(5)
  • 如何使用 WebAssembly 扩展后端应用
  • 0 -vscode搭建python环境教程参考(windows)
  • 【论文分享】三维景观格局如何影响城市居民的情绪
  • Vue3 虚拟列表组件库 virtual-list-vue3 的使用
  • JavaScript 单选框设置选中
  • 第5章-总体设计 5.2 需求转化为规格
  • java中设计模式的使用(持续更新中)
  • Mac解压包安装MongoDB8并设置launchd自启动
  • ‘视’不可挡:OAK相机助力无人机智控飞行!
  • pycharm分支提交操作