不到十个例题带你拿下c++双指针算法(leetcode)

news2024/10/3 8:26:49

移动零问题

https://leetcode.cn/problems/move-zeroes/submissions/

1.题目解析

必须在原数组进行修改,不可以新建一个数组

非零元素相对顺序不变

2.算法原理

【数组划分】【数组分块】

这一类题会给我们一个数组,让我们划分区间,比如说这题,最后会划分为两个区间,前一段是非零元素,后一段是零,一般我们只要看到这样的特性,脑海里就应该想到用双指针算法来解决(利用数组下标充当指针)

定义两个指针:

两个指针的作用:

cur :从左往后扫描数组,遍历数组。

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

如何做到:

cur从前往后遍历的过程中:

1.遇到0元素:cur++;

2.遇到非零元素:

交换

相关知识:快速排序

双指针的思想其实就是快排的核心思想

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

 

复写零问题

https://leetcode.cn/problems/duplicate-zeros/

1.题目解析

长度固定:不能越界

在原始数组进行操作

2.算法原理:

解法:双指针算法 先根据异地操作,然后优化成双指针下的“就地操作”

根据异地操作,得出先模拟一遍复写的操作,然后从后向前进行覆盖,从前往后会发生覆盖多的值。

总结:

1.先找到最后一个复写的数

用双指针模拟一遍 cur=0,dest=-1;

先判断cur位置的值,决定dest向后移动几步,判断dest是否已经到了最后的位置,cur++;

2.从后向前进行操作

特例:数组越界

所以要加上一个步骤:处理越界

3.解题代码:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur=0,dest=-1,n=arr.size();
        //先模拟
        while(cur<n)
        {
            if(arr[cur]) dest++;
            else         dest+=2;
            if(dest>=n-1) break;
            cur++;
        }
        //判断边界
        if(dest==n)
        {
            arr[n-1]=0;
            dest-=2;
            cur--;
        }
        //从后向前
        while(cur>=0)
        {
            if(arr[cur]==0)
            {
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
            else arr[dest--]=arr[cur--];
        }
    }
};

 

快乐数问题

https://leetcode.cn/problems/happy-number/

1.题目解析

一直替换

分为两种情况:

变成一

无限循环

两种情况

2.算法原理

有没有发现,一直平方到最后,一定会成环

解法:快慢双指针

1.定义快慢双指针

2.慢指针每次向后移动一步,快指针每次走两步

3.判断相遇的时候的值即可

双指针只是一种思想,不需要一定定义双指针,在这个题中快指针就是平方两次,慢指针平方一次

为什么会一定会重复

证明方法:

鸽巢原理(抽屉原理):

n个巢穴 n+1个鸽子-->至少有一个巢穴里面的鸽子数量大于1

3.解题代码

class Solution {
public:
    int Sum(int n)
    {
        int sum=0;
        while(n)
        {
            int g=n%10;
            sum+=g*g;
            n/=10;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow=n,fast=Sum(n);
        while(slow!=fast)
        {
            slow=Sum(slow);
            fast=Sum(Sum(fast));
        }
        return slow==1;
    }
};

盛水最多的容器

https://leetcode.cn/problems/container-with-most-water/

1.题目解析

只能水平放置,也就是找最大的矩形

2.算法原理

解法一:暴力枚举:双重循环

优点:想法简单

缺点:时间复杂度过高

解法二:头尾双指针:

v=h*w

宽度一直在减小,而高度有两种情况,变大或变小,在宽度一直在变小的情况下,我们高度必须选择更高的

3.解题代码


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

和为s的两个数字问题

1.题目解析

有序数组

随意输出一对

2.算法原理

解法一:暴力枚举 双重循环 n^2复杂度

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

首尾相加

判断数值,如果大于目标值,right--反之left++,因为数组是有序的

3.解题代码

vector<int> twosum(vector &nums,int t)
{
  int left =0,right=nums.size()-1;
  while(left<right)
  {
    int sum=nums[left]+nums[right];
    if(sum>t) right--;
    else if(sum<t) left++;
    else return {num[left],nums[right]};
  }
  //照顾编译器
  return {-1,-1};
}

有效三角形个数

https://leetcode.cn/problems/valid-triangle-number/

1.题目解析

相同的不算一个

2.讲解算法原理

补充数学知识:给我们三个数,判断是否能构成三角形

我们仅需要一个公式,就能判断是否能构成三角形:

如果我们已经知道三个数的大小顺序,只需要a+b>c(c是最大的数)

优化:先对整个数组排序

解法一:暴力枚举

for(i=0;i<n;i++)

for(j=i+1;j<n;j++)

    for(k=j+1;k<n;k++)

        check(i,j,k)

解法二:利用单调性,使用双指针算法来解决问题

①先固定最大的数

②在最大的数的左区间里,使用双指针算法,快速统计

3.解题代码

class Solution {
public:
    int triangleNumber(vector<int>& nums) 
    {
        int n=nums.size();
        int ret=0;
        sort(nums.begin(),nums.end());
        for(int i=n-1;i>=2;i--)
        {
            int left=0,right=i-1;
            while(left<right)
            {
                if(nums[left]+nums[right]>nums[i])
                {
                 ret+=right-left;
                 right--;
                }
                else
                {
                left++;
                }
            }
        }
        return ret;
    }
};

三数之和问题

https://leetcode.cn/problems/3sum/

1.题目解析

三个数的下标不同

答案不可重复(去重)

有可能没有答案

2.算法原理

解法一:先排序+暴力枚举+利用set去重o(n^3)

解法二:排序+双指针:

找到右边区间两数之和为左边数字的相反即可

1.排序

2.固定一个数a

3.在该数后边的区间,利用双指针的算法,快速找到和为-a的两个数

处理细节问题:

1.去重:

找到一种结果之后,left和right指针要跳过重复元素。

当使用完一次双指针算法之后,i也要跳过重复元素(避免越界)

2.不漏:

找到一种结果后,不要“停”,缩小区间,继续寻找

3。解题代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        int n=nums.size();
        for(int i=0;i<n;)
        {
            if(nums[i]>0) break;
            int left=i+1,right=n-1,t=-nums[i];
            while(left<right)
            {
                int sum=nums[left]+nums[right];
                if(sum<t) left++;
                else if(sum>t) right--;
                else
                {
                    ret.push_back({nums[i],nums[left],nums[right]});
                    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;
    }
};

四数之和

https://leetcode.cn/problems/4sum/

1.题目解析

三数之和的进阶版本,基本算法原理和三数之和大差不差

2.算法原理

解法一:排序+暴力枚举

四个循环,绝对超时

解法二:排序+双指针

1.依次固定一个数i

2.在i后面的区间内,利用三数之和找到三个数,让他们三个的和等于target-i;

{

1.依次固定一个j

2.在j后边的区间里,利用“双指针找到两个数,使得这两个数之和等于target-i-j”

}

处理细节问题:

不重,不漏

3.解题代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
              vector<vector<int>> ret;
            //1.排序
            sort(nums.begin(),nums.end());
            //2.利用双指针解决问题
            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)
                    {
                        int 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--]});
                        //去重1
                        while(left<right&&nums[left]==nums[left-1]) left++;
                        while(left<right&&nums[right]==nums[right+1]) right--;
                        }
                    }
                        //去重2
                j++;
                while(j<n&&nums[j]==nums[j-1]) j++;			
                }
                //去重3
                i++;
                while(i<n&&nums[i]==nums[i-1]) i++;
            }  
            return ret;
    }
};

觉得有帮助的惯用老爷麻烦点点关注!!!

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

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

相关文章

[项目管理-33/创业之路-87/管理者与领导者-127]:如何提升自己项目管理的能力和水平

目录 前言&#xff1a; 一、项目经理的角色定位 1.1 项目经理的职责 1.2 不同矩阵类型的项目&#xff0c;项目经理的职责 1.3 项目经理的角色定位 1.4 项目经理的发展路径 二、项目经理项目理论和知识结构 三、软件项目经理在计算机水平的提升 四、项目经理业务知识的…

海康Visionmaster-模块索引:MFC 模块索引异常解决 办法

现象&#xff1a;文件编码格式为 UTF-8 不带签名编码格式&#xff0c;模块索引会出现 模块无法找到异常 更改文件类型为 UTF-8 带签名格式或 vs 默认 GBK2312 编码格式

顺序表基本操作全面解析

文章目录 1.线性表2.顺序表分类2.1 静态顺序表2.2 动态顺序表 3. 顺序表各接口实现1. 定义结构体(Seqlist)2. 结构体初始化(SLInit)3.检查容量 (SLCheckCapacity)4.打印数据 (SLPrintf)5.插入操作5.1 从数据头部插入(SLPushFront)5.2 从数据尾部插入(SLPushBack)5.3 从任意下标…

控制论与科学方法论

《控制论与科学方法论》&#xff0c;真心推荐。 书籍原文电子版PDF&#xff1a;https://pan.quark.cn/s/aa40d59295df&#xff08;分类在学习目录下&#xff09; 备用链接&#xff1a;https://pan.xunlei.com/s/VNgj2vjW-Hf_543R2K8kbaifA1?pwd2sap# 控制论是一种让系统按照我…

C#学习相关系列之Linq用法---group和join相关用法(三)

一、Group用法 在C#的LINQ中&#xff0c;Grou将集合中的元素按照指定的键进行分组。Group方法返回一个IEnumerable<IGrouping<TKey, TElement>>类型的集合&#xff0c;其中TKey表示分组的键类型&#xff0c;TElement表示集合中元素的类型。每个IGrouping<TKey, …

Java(四)(多态,final,常量,抽象类,接口)

目录 多态 基本概念: 使用多态的好处 类型转换 遇到的问题 解决方法 强制类型转换的一个注意事项 final 常量 抽象类 啥是个抽象类? 抽象类的注意事项,特点 抽象类的场景和好处 抽象类的常见应用场景: 模板方法设计模式 接口 基本概念 接口的好处 JDK8开始,接…

Java之API(上)

前言&#xff1a; 这一次内容主要是围绕Java开发中的一些常用类&#xff0c;然后主要是去学习这些类里面的方法。 一、高级API&#xff1a; (1)介绍&#xff1a;API指的是应用程序编程接口&#xff0c;API可以让编程变得更加方便简单。Java也提供了大量API供程序开发者使用&…

【华为OD题库-032】数字游戏-java

题目 小明玩一个游戏。系统发1n张牌&#xff0c;每张牌上有一个整数。第一张给小明&#xff0c;后n张按照发牌顺序排成连续的一行。需要小明判断&#xff0c;后n张牌中&#xff0c;是否存在连续的若干张牌&#xff0c;其和可以整除小明手中牌上的数字. 输入描述: 输入数据有多组…

NLP学习

参考&#xff1a;NLP发展之路I - 从词袋模型到Transformer - 知乎 (zhihu.com) NLP大致的发展历史。从最开始的词袋模型&#xff0c;到RNN&#xff0c;到Transformers和BERT&#xff0c;再到ChatGPT&#xff0c;NLP经历了一段不断精进的发展道路。数据驱动和不断完善的端到端的…

逻辑漏洞(业务逻辑)dami CMS

逻辑漏洞&#xff08;业务支付逻辑漏洞&#xff09;dami CMS 0x01 业务逻辑简介 业务逻辑指的是一个系统或应用程序中的实际业务规则和流程。它描述了如何处理特定的业务需求、数据和操作。业务逻辑通常是根据特定行业或组织的需求而设计的。 在软件开发中&#xff0c;业务逻…

Matplotlib颜色条的配置_Python数据分析与可视化

Matplotlib颜色条配置 基本颜色颜色条选择配色方案颜色条刻度的限制与扩展功能的设置离散型颜色条 基本颜色 Matplotlib提供了8种指定颜色的方法&#xff1a; 在[0&#xff0c;1]中的浮点值的RGB或RGBA元组&#xff08;例如 (0.1, 0.2, 0.5) 或&#xff08;0.1&#xff0c; 0.…

MacOS 成为恶意软件活动的目标

Malwarebytes 警告称&#xff0c;一个针对 Mac 操作系统 (OS) 的数据窃取程序正在通过虚假的网络浏览器更新分发给毫无戒心的目标。 Atomic Stealer&#xff0c;也称为 AMOS&#xff0c;是 Mac OS 上流行的窃取程序。 Atomic Stealer (AMOS) 恶意软件最近被发现使用“ClearFa…

使用websocket获取thingsboard设备的实时数据

背景 有一个读者前来咨询,如何实时获取设备的遥测数据。 其实tb是有提供websocket接口来获取设备数据的。而且还支持js跨域调用。下面给大家演示一下。 websocket地址 完整代码 <!DOCTYPE HTML> <html><h

2023亚太杯数学建模赛题人工精准翻译

大家好&#xff0c;亚太杯今天早上6点已经开赛啦&#xff0c;然后我在这里给大家带来赛题的精准人工翻译&#xff0c;防止大家直接用软件翻译导致某些地方乱码或者翻译不精准&#xff0c;这会导致后续做题过程出现很大偏差。 注意&#xff0c;以下翻译均免费发放word形式的哈&…

自学成为android framework高手需要准备哪些装备-千里马车载车机系统开发学习

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01;经常有很多学员买课同学都会问到需要准备哪些装备&#xff0c;我也回答了很多学员了&#xff0c;今天就搞一篇文章来统一说明一下&#xff0c;告诉一下大家如果你想从一个framework新手变成一个framework开发的高…

【精选】CSS入门必看知识点大合集

CSS简介 CSS概念 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表 CSS文件后缀名为.css CSS用于HTML文档中元素样式的定义 为什么需要CSS 使用css的唯一目的就是让网页具有美观一致的页面 语法 CSS 规则…

VS Code 如何搭建C/C++环境

目录 一、VS Code是什么&#xff1f; 二、VS Code下载和安装 2.1下载 2.2安装 2.3环境介绍 三、Vs Code配置C/C环境 3.1下载和配置MinGW-w64编译器套件 3.1.1下载 3.1.2配置 一、VS Code是什么&#xff1f; 跨平台&#xff0c;免费且开源的现代轻量级代码编辑器 Vis…

vivado产生报告阅读分析15-时序报告11

Report Clock Domain Crossings “ Clock Domain Crossings (CDC) ” &#xff08; 时钟域交汇 &#xff09; 报告可对设计中的时钟域交汇执行结构分析。此信息可用于识别潜在不安全的 CDC &#xff0c; 此类 CDC 可能导致亚稳态或数据一致性问题。虽然 CDC 报告与“ Clock …

C#,数值计算——插值和外推,多项式插值与外推插值(Poly_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 多项式插值与外推插值 /// Polynomial Interpolation and /// Extrapolation interpolation routines for one dimension /// </summary> public class Poly…