算法思想总结:双指针算法

news2025/1/16 3:47:53

一、移动零

. - 力扣(LeetCode) 移动零

该题重要信息:1、保持非0元素的相对位置。2、原地对数组进行操作

 思路:双指针算法

class Solution {
public:
    void moveZeroes(vector<int>& nums)
    {
         int n=nums.size();
         for(int cur=0,des=-1;cur<n;++cur)
               if(nums[cur])//如为非零,就要与des后面的位置元素进行交换
                  swap(nums[++des],nums[cur]);
    }
};

 二、复写零

. - 力扣(LeetCode)复写零

该题的重要信息:1、不要在超过该数组的长度的位置写入元素(就是不要越界)2、就地修改(就是不能创建新数组)。3、不返回任何东西。

 思路:双指针算法

class Solution {
public:
    void duplicateZeros(vector<int>& arr)
    {
        int cur=0,des=-1,n=arr.size();
        //找最后一个被复写数的位置
        for(;cur<n;++cur)
        {
            if(arr[cur])
            ++des;
            else
            des+=2;
            if(des>=n-1)//要让des指向最后一个位置
            break;
        }
        //边界修正
        if(des==n)
        {
            arr[--des]=0;
            --des;
            --cur;
        }
        //从后往前复写
        for(;cur>=0;--cur)
        {
            if(arr[cur])
            arr[des--]=arr[cur];
            else
            {
                arr[des--]=0;
                arr[des--]=0;
            }
        }
    }
};

 三、快乐数

. - 力扣(LeetCode)快乐数

 该题的关键是:将正整数变成他的每位数的平方之和,有可能会一直循环始终到不了1,也有始终是1(快乐数)

思路:快慢双指针算法

以上的两个结论在博主的关于链表带环追击问题的文章里面有分析

顺序表、链表相关OJ题(2)-CSDN博客

class Solution {
public:
    int bitsum(int n)
    { 
        int sum=0;
        while(n)
        {
            int t=n%10;
            sum+=t*t;
            n/=10;//最后一位算完后拿掉
        }
        return sum;
    }

    bool isHappy(int n) 
    {
        int slow=n,fast=bitsum(n);
        while(fast!=slow)
        {
            slow=bitsum(slow);
            fast=bitsum(bitsum(fast));
        }
        return slow==1;
    }
};

四、盛最多水的容器

. - 力扣(LeetCode)盛最多水的容器

思路1、暴力枚举(时间复杂度太高)

class Solution {
public:
    int maxArea(vector<int>& height)
    {
        //暴力枚举
        int n=height.size();
        int ret=0;
          for(int i=0;i<n;++i)
             for(int j=i+1;j<n;++j)
                   ret=max(ret,min(height[i],height[j])*(j-i));
        return ret;
    }
};

思路2、双指针对撞算法

class Solution {
public:
    int maxArea(vector<int>& height)
    {
      int left=0,right=height.size()-1,ret=0;
      while(left<right)
      {
           ret=max(ret,min(height[left],height[right])*(right-left));
           if(height[left]<height[right])
           ++left;
           else
           --right;
      }
          return ret;
    }
};

五、有效三角形的个数

. - 力扣(LeetCode)有效三角形的个数

 思路1:升序+暴力枚举

思路2:升序+利用双指针算法

class Solution {
public:
    int triangleNumber(vector<int>& nums) 
    {
        //排序一下
        sort(nums.begin(),nums.end());
        //先固定一个数,然后用双指针去找比较小的两个数
        int n=nums.size(),ret=0;
         for(int i=n-1;i>=2;--i)
         {
            int left=0,right=i-1;
            while(left<right)
            {
                int sum=nums[left]+nums[right];
                if(sum<=nums[i])  ++left;
                else  
                {
                    ret+=(right-left);
                    --right;
                } 
            }
         }
         return ret;
    }
};

 六、查找总价格为目标值的两个商品

. - 力扣(LeetCode)查找总价格为目标值的两个商品

 

思路1:两层for循环找到所有组合去计算

思路2:利用单调性,使用双指针算法解决问题

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) 
    {
           int n=price.size();
           int left=0,right=n-1;
           while(left<right)
           {
               int sum=price[left]+price[right];
               if(sum>target) --right;
               else if(sum<target) ++left;
               else return {price[left],price[right]};
           }
           return {1,0};
    }
};

七、三数之和

. - 力扣(LeetCode)三数之和

解法1:排序+暴力枚举+set去重

解法2:排序+双指针

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums)
    {
        vector<vector<int>> ret;
        int n=nums.size();
        //先排序
        sort(nums.begin(),nums.end());
        //先固定一个数
        for(int i=0;i<n;)
        {
             if(nums[i]>0) break;//小优化
            int target =-nums[i];//目标值
            //定义双指针
            int left=i+1,right=n-1;
            while(left<right)
            {
                int sum=nums[left]+nums[right];
                if(sum<target)  ++left;
                else if(sum>target) --right;
                else  
                {
                   ret.push_back({nums[left],nums[right],nums[i]});//插入进去
                   ++left;
                   --right;
                   //去重
                   while(left<right&&nums[left]==nums[left-1])  ++left;//去重要注意边界
                   while(left<right&&nums[right]==nums[right+1])  --right;
                }
            }
            ++i;
            while(i<n&&nums[i]==nums[i-1])  ++i;//去重要注意边界
        }
               return ret;
    }
};

八、四数之和

. - 力扣(LeetCode)四数之和

 

解法1:排序+暴力枚举+set去重

解法2:排序+双指针(和上一题基本一样,无非就是多固定了一个数)

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
       vector<vector<int>> ret;
       //先进行排序
       sort(nums.begin(),nums.end());
       //利用双指针解决
       int n=nums.size();
       //先固定一个数
       for(int i=0;i<n;)
       {
          //再固定一个数
          for(int j=i+1;j<n;)
          {
            int left=j+1,right=n-1;
            long long aim=(long long)target-nums[i]-nums[j];//确保不超出范围
            while(left<right)
            {
             long long sum=nums[left]+nums[right];
            if(sum<aim)  ++left;
            else if(sum>aim) --right;
            else 
            {
            ret.push_back({nums[i],nums[j],nums[left],nums[right]});
                ++left;
                --right;
                //去重
                while(left<right&&nums[left]==nums[left-1]) ++left;
                while(left<right&&nums[right]==nums[right+1]) --right;
            }
            }
             //去重
          ++j;
          while(j<n&&nums[j]==nums[j-1]) ++j;
          }
          //去重
          ++i;
          while(i<n&&nums[i]==nums[i-1]) ++i;
          }
          return ret;
    }
};

九、总结

常见的双指针有三种形式:前后指针、对撞指针、快慢指针

1、前后指针:用于顺序结构,一般是两个指针同方向,cur指针用来遍历数组,des指针将数组进行区域划分。(如1、2题)

       注意事项:如果是从前往后遍历,要注意dst不能走得太快,否则cur还没遍历到一些数就会被覆盖掉,必要时候可以根据情况从后往前遍历。

2、快慢指针:其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。
这种⽅法对于处理环形链表或数组⾮常有⽤。(如第3题,以及链表带环的问题)

        注意事项: 其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。最常用的就是快指针走两步,慢指针走一步。

3、对撞指针:一般用于顺序结构。从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。并且常常会用到单调性!!(如4-8题)
        注意事项:对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环)

        如果后面还有关双指针的经典题目,博主会继续在这篇更新的!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1513673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:在本地使用 Gemma LLM 对私人数据进行问答

在本笔记本中&#xff0c;我们的目标是利用 Google 的 Gemma 模型开发 RAG 系统。 我们将使用 Elastic 的 ELSER 模型生成向量并将其存储在 Elasticsearch 中。 此外&#xff0c;我们将探索语义检索技术&#xff0c;并将最热门的搜索结果作为 Gemma 模型的上下文窗口呈现。 此外…

人工智能迷惑行为大赏!

目录 人工智能迷惑行为大赏 一&#xff1a;人工智能的“幽默”瞬间 1. 图像识别出现AI的极限 2. 小批量梯度下降优化器 3. 智能聊天机器人的冰雹问题 4. 大语言模型-3经典语录 二&#xff1a;技术原理探究 1. 深度学习 2. 机器学习 3. 自然语言处理 4. 计算机视觉 三…

java八股文 笔记(持续更新中~)

1 Redis 2Mysql 3JVM 4java基础底层 5 spring 6 微服务 7.......(持续更新) One:Redis篇 1.穿透 2&#xff1a;击穿 3&#xff1a;雪崩 3 33 4:双写一致 5.持久化 2 JVM: 2&#xff1a; 3&#xff1a; 4&#xff1a; 5&#xff1a; 6&#xff1a; 7&#xff…

学生时期学习资源同步-1 第一学期结业考试题1

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载

深度学习--离线数据增强

最近做项目遇见数据集背景非常单一&#xff0c;为了增加模型的返回能里&#xff0c;只能自己做一些数据增强来增加背景的多样性。代码如下&#xff1a; import numpy as np import cv2def create_mask(box, height, width):"""创建一个全零的掩码图像&#xff…

Prompt进阶2:LangGPT(构建高性能Prompt策略和技巧)--最佳实践指南

Prompt进阶2:LangGPT(构建高性能Prompt策略和技巧)–最佳实践指南 0.前言 左图右图 prompt 基本是一样的&#xff0c;差别只在提示工程这个词是否用中英文表达。我们看到&#xff0c;一词之差&#xff0c;回答质量天壤之别。为了获得理想的模型结果&#xff0c;我们需要调整设…

uniapp开发DAPP钱包应用(二) Vue + Java

上一节我们讲了如何通过vue uniapp还有web3以及需要准备的相关组件&#xff0c;来搭建了DAPP开发的环境。 这一节&#xff0c;我们来说说如何用代码来实现DAPP相关接口。 1. ethers实现类 导入组件 import { ethers , providers , utils } from "ethers"; impor…

跟着GPT学设计模式之桥接模式

说明 桥接模式&#xff0c;也叫作桥梁模式&#xff0c;英文是 Bridge Design Pattern。在 GoF 的《设计模式》一书中&#xff0c;桥接模式是这么定义的&#xff1a;“Decouple an abstraction from its implementation so that the two can vary independently。”翻译成中文就…

我真是服了!你们刚开始学习的时候也是造火箭吗?能不能有一个简单的纯纯纯html模板给我学学,真的看不懂好嘛!

做一个个人博客第一步该怎么做&#xff1f; 好多零基础的同学们不知道怎么迈出第一步。 那么&#xff0c;就找一个现成的模板学一学呗&#xff0c;毕竟我们是高贵的Ctrl c v 工程师。 但是这样也有个问题&#xff0c;那就是&#xff0c;那些模板都&#xff0c;太&#xff01;…

弧形导轨的设计要求

制造业设备种类越来越多&#xff0c;非标自动化设备渐渐成了主力市场&#xff0c;其中弧形导轨线体作为非标自动化运输中的基石&#xff0c;承担了运输&#xff0c;定位&#xff0c;特殊工位组装&#xff0c;其设计要求也非常严格。 1、精度要求&#xff1a;弧形导轨需要具备高…

大数据 - HBase《一》- Hbase基本概念

目录 1.1. Hbase简介 1.2 Hbase,Hive, Mysql对比 1.3 Hbase数据模型 &#x1f959;region(区域) &#x1f959;rowkey(行键) &#x1f959;列族&#xff08;column family) &#x1f959;列&#xff08;column Qualifier) &#x1f959;版本&#xff08;version)-默认按…

如何仅用3行代码,搞定业务敏感数据加解密?

01 引子&#xff1a;一个数据安全的故事 一个风和日丽的早上&#xff0c;某家快递物流公司内。 &#xfeff;张老板看着电脑屏幕&#xff0c;眉头紧锁。电脑屏幕上赫然写着&#xff0c;“疑似45亿条个人信息泄露&#xff0c;电商物流行业数据安全警铃再响”。据传&#xff0c;…

代码学习记录18

随想录日记part18 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.13 主要内容&#xff1a;今天的主要内容是二叉树的第七部分&#xff0c;主要涉及二叉搜索树的最近公共祖先 &#xff1b;二叉搜索树的最近公共祖先&#xff1b;删除二叉搜索树中的节点 。 23…

国内使用GPT4的5种解决方案,最后一个是全场最佳

ChatGPT4是目前世界上最先进的自然语言处理模型 大家都知道ChatGPT4特别好用 我个人来说&#xff0c;基本上每天都会用GPT来查资料、写代码和润色文章 但是在国内&#xff0c;使用ChatGPT4&#xff0c;是有一定门槛的 门槛一 mo法问题 ChatGPT的网站&#xff0c;国内是无法访问…

javaEE13(网站第8章两个课后题)

1、对“jspservletjavabean实现分页查询”功能做如下补充&#xff1a; &#xff08;1&#xff09;记录批量删除&#xff1a;每个记录前添加复选框&#xff0c;点击批量删除&#xff0c;删除选中记录。 增加跳转到任意页功能。用户可改变每页记录条数。 页面&am…

ImportError: Plotly express requires pandas to be installed.

在 Python3 环境下&#xff0c;使用 plotly 绘图时&#xff0c;发生了如下错误&#xff1a; ImportError: Plotly express requires pandas to be installed. 通过排查发现是使用了折行导入时报错的&#xff1a; import plotly.express as px 通过检索找到了解决办法&#xff0…

VScode Error Lens插件

安装完成之后&#xff0c;当我们输入一些错误的语法格式的时候&#xff0c;它都会有一些提示&#xff01; 一开始是英文提示 修改为中文提示 设置搜索 typescript.local

【gpt实践】李某的AI课程值199吗

先说个人的答案&#xff1a;不值。但也不是说毫无价值&#xff0c;只是他的价值没那么高。 文末分享该课程&#xff0c;大家有兴趣可以看看&#xff0c;该课程是否有价值。 “清华博士”推出的199元的AI课程销售额竟然突破了5000万。这一数字让人惊叹&#xff0c;也引发了人们…

免费AI软件开发工具测评:iFlyCode VS CodeFlying

前言 Hello&#xff0c;各位看官&#xff0c;今天为大家带来两款人工智能的软件开发工具的测评&#xff0c;他们分别是iFlyCode和CodeFlying&#xff0c;我相信当大家看到这两款产品名字的时候不禁都会有些好奇&#xff0c;两个产品都有Code 和Fly两个元素&#xff0c;那他们之…

Consul 配置持久化

当我们在consul的key-value中配置了几个字段 访问后的结果: 但是当我们在控制台输入命令重启consul服务后: consul agent -dev 刚刚设置的key-value值便消失不见了 此时就要进行 consul 持久化配置. 第一步:在consul文件夹下创建 1.空文件夹mydata 2.新建文件consul_star…