优选算法精品课--双指针算法(2)

双指针算法(2)

  • 1、有效三角形的个数
    • 1.1 题目解析
    • 1.2 思路解析
    • 1.3 代码实现
  • 2、和为s的两个数
    • 2.1 题目解析
    • 2.2 思路解析
    • 2.3 代码实现
  • 3、三数之和
    • 3.1 题目解析
    • 3.2 思路解析
    • 3.3 代码实现
  • 4、四数之和
    • 4.1 题目解析
    • 4.2 思路解析
    • 4.3 代码实现
  • 5 总结

1、有效三角形的个数

题目链接:
https://leetcode.cn/problems/valid-triangle-number/

1.1 题目解析

在这里插入图片描述
题目的意思就是让我们选出所有能组合为一个三角形的三个数的组合,并且如图两个二算两种。

1.2 思路解析

首先三角形成立的条件是两边之和大于第三边,两边之差小于第三边,但是如果我们按这个条件
来判断成立三角形的话可以倒是可以,但是太麻烦了,现在我们有一种新的思路:
假设:2 3 4是三角形三条边,那我们是不是可以只需要判断2+3>4即可,为什么呢?
因为2+4一定大于3,3+4一定大于2,3-2一定小于4、
当2+3>4成立时一定有4-3<2,4-2<3.

所以第一步我们需要将数组排序(这样更好找最大最小值)

在这里插入图片描述
然后我们固定第三条边和第一条边,我们通过改变第二条边来判断该组合是否成立:
这里有两种情况:
1、arr[o]+arr[t]>arr[tr],在这种情况下,arr[o]后面的所有值与arr[t]相加都大于arr[tr];
所以这种情况只需要计算区间的大小,区间的大小就是组合的数量

2、arr[o]+arr[t]<=arr[tr],这种情况下,无论我们如何移动左区间,和都小于arr[tr],所以我们现在要移动右区间,直到arr[o]+arr[t]>arr[tr];

大家下来可以画画图来理解一下.

总结:
在这里插入图片描述

1.3 代码实现

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());//算法库里的排序int tail=nums.size()-1;//最大边int count=0;//计数while(tail>=2)//第三条边必须要在第三个数组元素及以后{int left=0;//最小边int right=tail-1;while(left<right){if(nums[left]+nums[right]>nums[tail]){count+=right-left;right--;}else{left++;}}tail--;}return count;}
};

2、和为s的两个数

题目链接:
https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/

2.1 题目解析

在这里插入图片描述
这道题的意思就是需要我们在数组中找两个数,它们的和为target,只需要返回任意一组即可。

2.2 思路解析

这道题是不是类似于第一题啊,这一题我们的思路是:
在这里插入图片描述

假设这是我们的数组,我们还是需要先排序,然后计算arr[left]+arr[right]的和,在与target比较即可

三种情况:
‘<‘,这种情况我们直接left++即可
’>’,这种情况我们需要让right–;
‘==’,这组值就是我们需要的。

总结:
在这里插入图片描述

2.3 代码实现

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

3、三数之和

题目链接
https://leetcode.cn/problems/3sum/

3.1 题目解析

在这里插入图片描述
这道题难度就上来了,需要我们找出三个和为0的值,并且需要我们将相同组合给去掉(元素相同,顺序不同算同一组合)。

3.2 思路解析

解法一:暴力遍历,求出所有组合,通过容器set去重(太麻烦了)

解法二:双指针算法

现在这里的思路是先固定左边的一个数,这个数右边的部分作为一个区间,将左边这个数的相反数作为target,在右边的区间求两数之和等于target,这样我们的问题就变为求两数之和了。

在这里插入图片描述
重复上述操作,但是这道题难的部分是去重(去掉相同组合)。

去重需要注意的是这里由两部分需要去重:
第一部分是找到当前组合后left需要++,right需要- -,要是遇到相同元素需要跳过
第二部分是最左边的target遇到相同元素也需要去重

总结:
在这里插入图片描述

3.3 代码实现

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

4、四数之和

题目链接
https://leetcode.cn/problems/4sum/

4.1 题目解析

在这里插入图片描述
这道题与上面的三数求和十分类似,需要我们求四个数的和。

4.2 思路解析

上一题三数求和是在左边固定一个数,然后在右区间找两数,两数等于左边那个数的相反数,
这道题需要我们找四个数,那我们可以在左边固定两个数,然后右边的部分作为右区间,需要target-左边两个数=右边两数之和,完全类似,但是这道题需要注意的是int可能会溢出,我们需要使用long long,
其次三数求和是两个循环,需要注意两个地方的去重
而这里是三个循环,需要注意三个地方的去重:
1、left与right部分
2、左边两数中右边那数的去重
3、左边两数中最左边那个数的去重

总结
在这里插入图片描述

4.3 代码实现

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>>  vv;sort(nums.begin(),nums.end());int n=nums.size();for(int i=0;i<=n-4;){for(int j=i+1;j<=n-3;){int left=j+1,right=n-1;long long aim=(long long)target-nums[i]-nums[j];while(left<right){if(nums[left]+nums[right]<aim) left++;else if(nums[left]+nums[right]>aim) right--;else{vv.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-1]==nums[j]) j++;}i++;while(i<n&&nums[i-1]==nums[i]) i++;}return vv;}
};

5 总结

1、双指针常用于数组中元素的操作,但其他地方例如快乐数也可以使用,总的来说看到数组我们可以优先考虑双指针是否可行,然后考虑其他算法

2、在数组中对元素操作我们尽量都要画图,一定要考虑特殊情况,否则会把我们坑得死死的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4个提取音频办法,轻松实现视频转音频!

在信息爆炸的时代&#xff0c;视频内容以其直观、生动的特点占据了互联网的大半江山。然而&#xff0c;在某些场景下&#xff0c;我们可能更倾向于只听取音频部分&#xff0c;无论是驾驶途中听讲座、跑步时享受音乐视频中的纯音乐的场景&#xff0c;还是为了节省流量和存储空间…

Python continue和break

continue的作用是&#xff1a; 中断所在循环的当次执行&#xff0c;直接进入下一次 break的作用是&#xff1a; 直接结束所在的循环 注意事项&#xff1a; continue和break&#xff0c;在for和while循环中作用一致 在嵌套循环中&#xff0c;只能作用在所在的循环上&#x…

【01初识】-初识 RabbitMQ

目录 学习背景1- 初识 MQ1-1 同步调用什么是同步调用&#xff1f;小结&#xff1a;同步调用优缺点 1-2 异步调用什么是异步调用&#xff1f;小结&#xff1a;异步调用的优缺点&#xff0c;什么时候使用异步调用&#xff1f; 1-3 MQ 技术选型 学习背景 异步通讯的特点&#xff…

300元蓝牙耳机性价比高的有哪些?学生平价蓝牙耳机推荐

你是否正在为选择一款性价比高的蓝牙耳机而烦恼&#xff1f;是否希望找到一款既适合学生使用&#xff0c;又能在预算内满足需求的蓝牙耳机&#xff1f;300元蓝牙耳机性价比高的有哪些&#xff1f;如果你有这样的需求&#xff0c;那么下面我将为大家提供一些有益的参考&#xff…

中间件安全(三)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言: 本文主要讲解apache命令执行漏洞&#xff08;cve_2021_41773&#xff09;。 靶场链接&#xff1a;Vulfocus 漏洞威胁分析平台 一&#xff0c;漏洞简介。 cve_2021_41773漏洞…

【STM32外设及其应用】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

pyvideotrans 最佳AI翻译软件

文章目录 体验视频翻译配音工具主要用途和功能预打包版本(仅win10/win11可用&#xff0c;MacOS/Linux系统使用源码部署)MacOS源码部署Linux 源码部署Window10/11 源码部署源码部署问题说明使用教程和文档语音识别模型:视频教程(第三方)软件预览截图相关联项目致谢 体验 不错&a…

【含开题报告+文档+PPT+源码】基于SpringBoot的健康知识学习分享平台的设计与实现

开题报告 随着人们生活水平的提高和健康意识的增强&#xff0c;健康知识在日常生活中的重要性日益凸显。传统的健康知识获取途径如书籍、讲座等虽然具有一定的效果&#xff0c;但存在信息更新慢、交互性差等局限性。同时&#xff0c;互联网的普及和移动互联网的发展为人们提供…

【算法刷题指南】双指针

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

前端零基础入门到上班:【Day1】什么是前端?

本来打算开付费专栏 但是想起那句话 赠人玫瑰手留余香 引言1. 什么是前端&#xff1f;1.1 前端的定义1.2 前端的三大核心技术1.3 前端框架和工具 2. 什么是后端&#xff1f;2.1 后端的定义2.2 后端的组成要素2.3 后端框架和工具 3. 前后端的区别4. 什么是前后端分离&#xff1f…

院士领衔,瑞德磁电誓将中国红染遍磁电产业

【哔哥哔特导读】今天我们从广州来到淮北&#xff0c;参观一家由院士领衔创立的金属磁粉芯企业&#xff0c;看他们如何将中国红染遍磁电产业&#xff0c;一步步实现金属磁粉芯的国产替代。 想要成为一个领域的头部企业&#xff0c;技术实力与产能规模缺一不可&#xff0c;而瑞…

[翱捷]让SDK跑起来了

一&#xff0c;环境安排及验证 参照文档 <<ASR编译环境及编译步骤--3601.docx>> <<Windows环境搭建.docx>> <<ChildWatchSWUG_1221.doc>> 主要工具包括 ARM DS-5 V5.26.2 (64-bit)ActivePerl 5.28.1 Build 2801 (64-bit)msys2-x86_6…

摊牌了,创业失败了

“以为这个网红不会塌房&#xff0c;结果一觉醒来&#xff0c;天塌了……” ——某电商供应商 “这不是禁不住网上的各种诱惑吗&#xff0c;9月30日纵身入局&#xff0c;节假日几天不能买入&#xff0c;8号上班第一天我还看着钱数开心呢。结果今天……” ——一位投资失利&…

Python日志系统详解:Logging模块最佳实践

Python日志系统详解&#xff1a;Logging模块最佳实践 在开发Python应用程序时&#xff0c;日志记录是排查问题、监控系统状态、优化性能的重要手段。Python标准库中提供了强大的logging模块&#xff0c;使开发者可以轻松实现灵活的日志系统。本文将详细介绍Python的logging模块…

Java实现邮箱发送邮件添加定时任务(二)

上篇文章我们谈到邮件的发送&#xff0c;但是可以发现使用非常局限&#xff0c;这里我做了一个简单的修改&#xff0c;添加了定时发送功能&#xff0c;可以帮助我们处理很多繁琐的事 这里我写了一个简单的案例 1. 先在pom文件里面添加依赖 2.配置yml文件 3.写一个定时任务类…

python项目实战——多协程下载美女图片

协程 文章目录 协程协程的优劣势什么是IO密集型任务特点示例与 CPU 密集型任务的对比处理 I/O 密集型任务的方式总结 创建并使用协程asyncio模块 创建协程函数运行协程函数asyncio.run(main())aiohttp模块调用aiohttp模块步骤 aiofiles————协程异步函数遇到的问题一 await …

AI最新动态概览-2024年10月28日

1. 字节跳动加速欧洲布局&#xff0c;拟建AI研发中心 近日&#xff0c;有消息称字节跳动正积极筹备在欧洲设立AI研发中心&#xff0c;此举标志着该公司在全球技术版图上的又一重要扩张。随着人工智能技术的飞速发展&#xff0c;字节跳动正通过招兵买马&#xff0c;进一步巩固其…

Linux 进程优先级 进程切换

目录 优先级 概念 为什么优先级要限制在一定范围内 进程切换 方式 EIP寄存器(程序计数器) 进程在运行时会使用寄存器来保存临时数据 进程的上下文是什么&#xff1f; 进程的上下文保存到哪&#xff1f; 内核栈或专门的上下文结构也在内核空间&#xff1f;那为什么不直…

java 提示 避免用Apache Beanutils进行属性的copy。

避免用Apache Beanutils进行属性的copy。 Inspection info: 避免用Apache Beanutils进行属性的copy。 说明&#xff1a;Apache BeanUtils性能较差&#xff0c;可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier。 TestObject a new TestObject(); TestObject b new Te…

2024 最新 frida技术栈 第一部分

目录 1.下载 2. 安装 2.1. 命令 3.基本使用 3.1 列出运行的APP 3.2 列出所有APP 3.3 杀死进程 4. frida hook 方法 4.1 frida客户端命令行的参数 4.2. Frida两种操作模式 4.3. Frida操作APP的两种方式 4.3.1. attach模式 4.3.2. spawn模式 4.3.3 转发端口启…