双指针算法总结

news2024/12/24 20:47:10

双指针算法大致有以下几个类型

  • 对撞指针:一般用来处理两数和问题
  • 快慢指针: 一般在链表中用的比较多,如求链表中间结点,链表是否有环等,当然一些非链表题也会用到相关的思想
  • 区间划分: 将数组分成两个不同性质的两个部分

 一、对撞指针

1.盛⽔最多的容器(点击这里,直达题目)

 看到这题,最直接的想法就是暴力,两层for循环直接枚举左右端点,在所有的情况中找到最大值,时间复杂度是O(n^2),过不了,那么我们怎么优化时间复杂度?

这两个问题就是双指针思路的关键,这里就解释一下为什么是方案1,因为S=h * w,而此时的w只能减小,那么我们如果想让S变大,就只能将h变大,而h是由两边较低的高度决定的,如果我们移动较高的那条边,那么h就会受限于较低的那条边的高度,所以S只会变小,这就导致我们只能移动较低的那条边,而这也就能保证这个算法的正确性,即我们是将没有枚举到的情况排除了,并不是说枚举漏了,代码如下

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

2.和为s的两个数字(点击这里,直达题目)

 

 这题当然也是可以直接暴力枚举,两层for循环结束,时间复杂度是O(n^2),但是题目中给的排序条件我们没有用上,那么我们如何利用这个条件优化时间复杂度?

选方案2,理由如下

因为s=17,而target=9,所以我们需要让s变小,而中间的元素都比nums[left]大,比nums[right]小,如果移动left,只能让s更大,所以我们移动right,让s减小,如果遇到s<target的情况,就移动left,理由同上,而我们能这么做的根本原因在于数组有序,(思路的正确性的分析同上一题)

代码如下

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

当然我们还能求s<target的数字对个数,s>target的数字对个数等等,同样的分析方法,就留给大家做练习了。

总结一下:能否使用对撞指针,主要看是否满足"单调性",即在固定其中一个指针的情况下,left和right从逻辑上来说只能有一个发生移动,当我们不确定时,就照着上面的分析方法试试看

二、快慢指针

这个一般在链表中用的比较多,很多链表的经典题目都会用到,这里就不细讲在链表中的应用了,一般链表的题目大家都很容易想到这个思想,但是一旦题目脱离了链表,我们基本就不会有意识的想到这种思想,如下面这道题

快乐数(点击这里,直达题目)

 这道题的关键就在于无限循环因为如果你对链表很熟悉的话,你就会想到链表有环的相关问题,然后你就会想到快慢指针,而这就是这道题的解法

好,我们来看一下这道题,就是判断数是否是快乐数,如果是,那么在经过一段重复的操作之后,会变为1,如果不是,则会一直循环,本质不是和判断链表是否有环一摸一样的问题吗?没环,则链表会走到NULL,有环,则一直循环。至于有人说的无限循环,也可能是走一直不重复的数字,这个问题后面会简单证明一下,这里就先默认要么为1,要么循环

代码如下

class Solution {
public:
    int Get(int x){
        int res=0;
        while(x){
            res+=(x%10)*(x%10);
            x/=10;
        }
        return res;
    }
    bool isHappy(int n) {
        int fast=Get(n),slow=n;
        while(fast!=slow)//如果相等停下来,1也可以看成循环,只是循环的数字一直是1
        {
            slow=Get(slow);//相当于链表中slow往后走一步
            fast=Get(Get(fast));//相当于链表中fast往后走两步
        }
        return slow==1;//判断是否是快乐数
    }
};

 总结一下:快慢指针的思想不是只能出现在链表中,我们要能通过题目给的信息找出它和链表题之间的关系,实现知识的迁移变形

三、区间划分

移动零(点击这里,直达题目)

 我们的思路是根据题目要求维护三个区间,被双指针分割出来的三个区间

 

 代码如下

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

这题的思路其实和快排中,选定目标值target,然后将数组分为<=target和>target两部分的实现一样,都是划分数组,维护区间,忘记的可以去回顾一下

总结一下:当遇到要将数组划分区间的题目时,可以想想能不能用双指针来做

当然这题用快慢指针的思想也能做,代码如下

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j=0;
        for(int i=0;i<nums.size();i++)
            if(nums[i])
                nums[j++]=nums[i];
        while(j<nums.size())
            nums[j++]=0;
    }
};

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

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

相关文章

生产作业标准化是什么?生产车间作业流程标准化的步骤

生产作业标准化是以精益化为目标&#xff0c;对现行作业方法进行量化细化的分析改善&#xff0c;最终形成优化后的更好的作业程序。标准化的作用主要是以文件的方式保存企业成员积累的技术和经验&#xff0c;而不是因为人员的流动而失去整个技术和经验。 生产作业标准化的实施非…

聚观早报|微博Q2营收31.4亿元;新能源车新一轮价格战再打响

【聚观365】8月25日消息 微博Q2营收31.4亿元 新能源车新一轮价格战再打响 网易云音乐上半年净利润3.32亿元 万物云上半年盈利10.5亿元 有道2023年Q2净收入12.1亿元 微博Q2营收31.4亿元 微博发布2023年第二季度财报。二季度微博总营收4.402亿美元&#xff0c;约合31.4亿元…

RabbitMQ集群搭建和测试总结_亲测

RabbiMQ简介 RabbitMQ是用Erlang开发的&#xff0c;集群非常方便&#xff0c;因为Erlang天生就是一门分布式语言&#xff0c;但其本身并不支持负载均衡。 RabbitMQ模式 RabbitMQ模式大概分为以下三种: (1)单一模式。 (2)普通模式(默认的集群模式)。 (3)镜像模式(把需要的队列…

python scrapy框架

scrapy概述 Scrapy&#xff0c;Python开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛&#xff0c;可以用于数据挖掘、监测和自动化测试 scrapy安装 pip install scrapy -i https://pypi.tuna.tsinghua…

【力扣】216. 组合总和 III <回溯、回溯剪枝>

【力扣】216. 组合总和 III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字 1 到 9&#xff0c;每个数字最多使用一次&#xff0c;返回所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回…

MindManager

MindManager 简介下载安装crack 简介 MindManager是一款由Mindjet公司开发的思维导图软件。思维导图是一种图形化的方法&#xff0c;用于在一个中心主题周围组织和呈现各种相关思想、想法和信息。MindManager允许用户创建、编辑和共享思维导图&#xff0c;以帮助他们更好地组织…

Source Insight 宏-局部替换

编码中有没有遇到这种情况&#xff1a;添加一个新的函数&#xff0c;参考某某函数。然后我们新加一个函数名&#xff0c;把某某函数的内容全部拷贝过来&#xff0c;参数不一样时&#xff0c;再把拷贝过来的内容里的参数全部替换成新的参数。source insight 里替换的命令是ctrlh…

电商项目part06 微服务网关整合OAuth2.0授权中心

微服务网关整合 OAuth2.0 思路分析 网关整合 OAuth2.0 有两种思路&#xff0c;一种是授权服务器生成令牌, 所有请求统一在网关层验证&#xff0c;判断权 限等操作&#xff1b;另一种是由各资源服务处理&#xff0c;网关只做请求转发。 比较常用的是第一种&#xff0c;把API网关…

Linux内核学习(九)—— 虚拟文件系统(基于Linux 2.6内核)

虚拟文件系统&#xff08;VFS&#xff09;作为内核子系统&#xff0c;为用户空间程序提供了文件和文件系统相关的接口。通过虚拟文件系统&#xff0c;程序可以利用标准的 Unix 系统调用对不同的文件系统&#xff08;甚至不同介质上的文件系统&#xff09;进行读写操作。 一、通…

人力资源小程序的设计原则与实现方法

随着移动互联网的快速发展&#xff0c;小程序成为了各行各业推广和服务的新利器。对于人力资源行业来说&#xff0c;开发一款定制化的小程序不仅可以提升服务效率&#xff0c;还可以增强品牌形象和用户粘性。那么&#xff0c;如何定制开发人力资源类的小程序呢&#xff1f;下面…

数组和指针练习解析(6)

题目&#xff1a; int main() { char *c[] {"ENTER","NEW","POINT","FIRST"}; char**cp[] {c3,c2,c1,c}; char***cpp cp; printf("%s\n", **cpp); printf("%s\n", *--*cpp3)&#xff1b; printf("%s\n&…

Unity3D Pico VR 手势识别

本文章使用的 Unity3D版本: 2021.3.6 , Pico SDK 230 ,Pico OS v.5.7.1 硬件Pico 4 Pico SDK可以去Pico官网下载SDK 导入SDK 第一步&#xff1a;创建Unity3D项目 第二步&#xff1a;导入 PICO Unity Integration SDK 选择 Windows > Package Manager。 在 Packag…

巴别塔再现?高质量端到端数据助力Meta推出AI模型SeamlessM4T

追求卓越与无限的精神一直流淌在人类的基因里。圣经中有故事&#xff1a;在古代&#xff0c;人们说着同一种语言&#xff0c;决定建造一座高耸入云&#xff0c;塔顶能触及天堂的塔&#xff0c;被称为巴别塔&#xff0c;以彰显人类的力量和创造力。然而上帝看到人类的意图&#…

数据科学 × 临床医学丨和鲸打造可供科研多角色协同的低代码研究平台

领域背景&#xff1a;临床研究的“多角色”性 临床研究是以疾病的诊断、治疗、预后和病因为主要研究内容&#xff0c;以患者为主要研究对象的科学研究活动。现代临床研究项目的开展具有“多角色”参与的特性&#xff0c;除了发起项目的 PI 外&#xff0c;项目的核心团队可能还…

14-模型 - 增删改查

增: # 1. 找到模型类并创建对象 user User() # 2. 给对象的属性赋值 user.username username user.password password user.phone phone # 3. 将user对象添加到session中 (类似缓存) db.session.add(user) # 4. 提交数据 db.session.commit() 删: # 两种删除:# 1. 逻辑删…

C++核心编程:类和对象

总览 C 面向对象的三大特性&#xff1a; 封装&#xff0c;继承&#xff0c;多态 C认为 万事万物都皆为对象&#xff0c;对象上有其属性和行为 封装 封装的意义 封装是C面向对象的三大特征之一 封装的意义&#xff1a; 将属性和行为作为一个整体&#xff0c;表现生活中的事…

芯科科技推出专为Amazon Sidewalk优化的全新片上系统和开发工具,加速Sidewalk网络采用

芯科科技为Sidewalk开发提供专家级支持 中国&#xff0c;北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今日在其一年一度的第四…

安防监控平台EasyCVR视频汇聚平台增加首页告警类型的详细介绍

安防监控/视频集中存储/云存储EasyCVR视频汇聚平台&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等…

kubernetes--技术文档--可视化管理界面dashboard安装部署

阿丹&#xff1a; 使用官方提供的可视化界面来完成。 Kubernetes Dashboard是Kubernetes集群的Web UI&#xff0c;用户可以通过Dashboard进行管理集群内所有资源对象&#xff0c;例如查看资源对象的运行情况&#xff0c;部署新的资源对象&#xff0c;伸缩Deployment中的Pod数量…

SAP 之如何定义功能范围Function Area

目录 目录 前言 一、注意点 二、使用步骤 1. Step by step 2. 其它功能 总结 前言 在SAP中&#xff0c;FA功能范围是一个组织单元&#xff0c;一般根据活动对产生的运营费用进行分类。例如生产、管理、销售、研发等&#xff0c;可以分配给成本中心Cctr、GL总账科目、Ord…