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

【双指针】算法题(一)

【双指针】算法题(一)

前言:

本章只有两道算法题:移动零、复写零。

常见的双指针有两种形式,一种是对撞指针,一种是左右指针。

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

2.**快慢指针:**基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。(就不如链表使用的快慢指针,每次fast向后移动两步,slow向后移动一位,两个指针速度不同)

题目一:移动零

题目链接在这里,点击即可

题目描述:
在这里插入图片描述

算法分析:

  1. 先定义两个指针,cur 和 dest ,cur 用来遍历数组,dest用来记录数组的最后一个元素的位置。
  2. 先思考,本题要求在一个数组里面实现把零全部移动到数组的后面,cur 在遍历数组的时候,会遇到不同的情况:使[0, dest] 的元素全部都是非零元素, [dest + 1, cur - 1] 的 元素全是零。

算法流程:

  1. 定义两个指针,int cur=0(用于遍历数组);int dest=-1(指向非零元素序列的最后⼀个位置。 因为刚开始我们不知道最后⼀个非零元素在什么位置,因此初始化为-1);cur不大于数组元素个数。
  2. 开始时,首先移动cur,若cur指向的元素的值为0,dest不变,cur继续向后移动;若cur指向的元素的值不为零,则dest向后移动一位,然后与cur指向的元素进行交换,然后cur再向后移动一位。

算法代码1(这是用for循环的):

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

算法代码2(这是用while循环的,思路跟上面一样,只是代码展现形式不一样,用while循环两个指针的起始位置可以是相同的):

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


        }
    }
};

题目二:复写零

题目链接在这里

题目描述:
在这里插入图片描述

算法分析:

如果从前向后进行原地复写操作的话,由于0 的出现会复写两次,导致没有复写的数被覆盖掉。因此我们选择从后往前的复写策略。 但是从后向前复写的时候,我们需要找到最后一个复写的数,因此我们的大体流程分两步:

  • 先找到最后一个复写的数
  • 然后再从后向前复写0

算法流程:

  1. 先定义两个指针,int cur=0;int dest=0;
  2. 然后找到最后一个复写的数
    • cur小于arr.size(),判断cur位置的值,用cur从前往后遍历,当cur遇到0,dest向后移动两位;当cur遇到不为0的数时,dest向后移动一位。
    • 判断dest是否到达数组的最后一位,终止循环,若没有到达,则cur继续往后移动一位,继续判断。
  3. 判断dest是否越界(这里是考虑一种特殊的情况,当cur位置的是0的时候,dest位于数组的倒数第二位,再复写的时候有一个0是越界了的)
    • 若dest越界,则让arr[arr.size()-1]=0;
    • 然后让cur往前移动一位,dest往前移动两位,即cur–,dest-=2
  4. 最后从后往前遍历
    • 如果cur位置的值为0,则arr[dest–]=0;arr[dest–]=0,(这步复写0,所以写两次arr[dest–]=0);
    • 如果cur位置的值不为0,则将arr[cur–]值赋给arr[dest–]

代码实现:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur=0;
        int dest=-1;
        while(cur<arr.size())
        {
            if(arr[cur]==0)
            {
                dest+=2;
            }
            else
            {
                dest++;
            }
            if(dest>=arr.size()-1)
            {
                break;
            }
            cur++;
        }
        if(dest==arr.size())
        {
            arr[arr.size()-1]=0;
            cur--;
            dest-=2;
        }
        while(cur>=0)
        {
            if(arr[cur]==0)
            {
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
            else
            {
                arr[dest--]=arr[cur--];
            }
             
        }


    }
};

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

相关文章:

  • Ribbon
  • 软考-信息安全-网络安全体系与网络安全模型
  • [OpenGL]使用 Compute Shader 实现矩阵点乘
  • TDengine 新功能 VARBINARY 数据类型
  • MacOS安装Xcode(非App Store)
  • 决策树python实现代码1
  • JavaSE(基础篇-进阶篇day03)
  • docker 使用 xz save 镜像
  • 如何构建一个可信的联邦RAG系统。
  • 如何在centos系统上挂载U盘
  • 回归预测 | MATLAB实现CNN-BiGRU卷积神经网络结合双向门控循环单元多输入单输出回归预测
  • 显卡检测工具再升级,GPU-Z v2.61.0全新硬件支持
  • 探索Web3的核心原则:去中心化与用户控制
  • vue 将数据生成为txt、execl并下载
  • 单片机:实现流水灯左移、右移程序(附带源码)
  • 51c大模型~合集91
  • mobilenetv2-inceptionv3-resnet50三大模型对比实现人脸识别反欺诈系统【带UI界面】
  • 矽睿半导体专为汽车领域研发出一系列应用型霍尔传感器
  • CentOS系统安装rustup
  • EPMA技术:高效率分析仪器的原理与应用-测试狗
  • 贝叶斯推断的条件观点
  • Redis 附加功能(三)— 持久化、发布与订阅及模块
  • 计算机基础知识——数据结构与算法(二)(山东省大数据职称考试)
  • Linux服务器上安装JDK1.8
  • ilqr算法原理推导及代码实践
  • 音视频入门基础:MPEG2-TS专题(19)——FFmpeg源码中,解析TS流中的PES流的实现