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

双指针算法——配合例题讲解

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

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

        *对撞指针从两端向中间移动。一个指针从最左段开始,另一个从最右端开始,然后逐渐往中间逼近

        *对撞指针的终止条件一般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是

                left == right  (两个指针指向同一个位置)

                left >right (两个指针错开)

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

        *这种方法对于处理环形链表或数组非常有效

        *如果要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想

        *快慢指针的实现方法有很多种,最常用的一种就是:在一次循环中,每次让慢的指针向后移动一位,而快的指针向后移动两位,实现一快一慢

        这道题的意思是让0移到末尾,非0元素的相对位置并不发生改变,这道题的解法来源于快排的第三种写法,有兴趣的可以看看我以前的文章

        我们定义两个指针(并不是传统意义上的指针实际上只是数组的小标),cur和dest,我们需要保证的就是cur和dest之间的数全是0(就类似快排中两个指针中间的数全部大于选定的key),我们将cur初始化为0,dest可以初识化为-1(其他负数也可以,但是这样可以省去一些边界处理),这个初识化要保证一开始这个区间并不存在

        然后我们让cur向后走,如果遇到0直接++遇到非零让dest++并交换nums[left]和nums[right]。

        

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

        这道题题的意思是遇到0将0后面的数向后移一位让后将0后空出来的位置填为0,这个题一开始我是想暴力的也是两个指针(up和down),但是还开了一个和arr一样大的vector,每次都让up向后走但终止条件时down越界,如果arr[up]是非零直接填到新开的表同时down++,如果arr[up] == 0就让down和down+1处的新开表的值为0然后down向后移两位。

        第二种方法是通过确定复写后的数组的最后一个元素的值,来在原表操作。

        确定最后一个元素的方法就是双指针,一个cur一个dest,dest表示已操作部分的末尾开始是因为没有已操作部分所以dest初始化为-1,cur初识化为0

        当arr[cur] == 0时dest+=2,否则dest++每次cur都需要++,如果dest>=arr.size()-1就结束循环

        如果这个时候dest == arr.size()就需要边界处理将arr[arr.size()] = 0,然后dest-=2,cur--

        然后开始复写arr

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

    }
};

相关文章:

  • 镭神C32测试LEGO-LOAM
  • IntelliJ IDEA 2021版创建springboot项目的五种方式
  • 深度解析前端页面性能优化
  • Python与SQL深度融合实战案例:打造你的数据处理秘籍
  • C++后端服务器开发技术栈有哪些?有哪些资源或开源库拿来用?
  • 嵌入式八股C语言---指针与函数篇
  • ESP8266 入门(第 2 部分):使用 AT 命令
  • c#面试题整理7
  • JavaScript系列07-事件委托:深入剖析与实践技术
  • LeetCode 1876长度为三且各字符不同的子字符串
  • 【数据结构】-- LinkedList与链表(1)
  • Docker 实践与应用举例
  • CCF-CSP第27次认证第1题 --《如此编码》
  • 大模型量化技术原理总结 [吃果冻不吐果冻皮]
  • 自然语言处理:最大期望值算法
  • 从案例分析看微型工业计算机在智能社区中的卓越表现
  • Springboot redis bitMap实现用户签到以及统计,保姆级教程
  • SpringBoot全栈开发:从数据库到Markdown文件导出的终极实践指南
  • TCP协议与包头格式
  • 计算机视觉中的前向卷绕算法全解析
  • 网站建设mdf/关键词搜索趋势
  • 江苏优化网站公司/搜索引擎优化排名工具
  • 定制开发网站的公司/专业做网站的公司
  • 合肥网站建设第一品牌/网站运营培训学校
  • 书籍扉页页面设计模板/seo流量的提升的软件
  • 天津市工程建设公众信息网官网/武汉seo网站推广培训