C++ 优先算法 —— 三数之和(双指针)

目录

题目:三数之和 

1. 题目解析

2. 算法原理

①.  暴力枚举

②.  双指针算法

不漏的处理:

 去重处理:

 固定一个数 a 的优化:

3. 代码实现

Ⅰ.  暴力枚举(会超时 O(N³))

Ⅱ.  双指针算法 (O(N²))


题目:三数之和 

1. 题目解析

题目截图:

 

题目中所述的顺序不重要有两种情况:

  1. 最终选出来的几个三元组里,每个三元组里的数据顺序,是可以不用考虑的。
  2. 最终选出来的几个三元组,三元组的顺序,也是可以不用考虑的。

题目中还要求元素不能相同:

 

 

题目的细节要求也就是:

  • 最终选出来的几个三元组里面的元素是对应不同的 
  • 返回的三元组及其三元组里的数据的顺序不重要。 

  

题目给的示例二就是没有最终结果的情况

 

2. 算法原理

这道题有两种解法:

  • 暴力枚举(但会超时)
  • 双指针算法

①.  暴力枚举

虽然暴力枚举会超时,这里还要介绍一下的,因为双指针解法就是基于暴力枚举进行优化的。

这里方法就是:排序+暴力枚举(从左往右)+去重

 这里排序去重要注意的是:

所以可以换个策略,先对原数组整个排序:

所以,也就是先排序,再暴力枚举(从左往右枚举),再去重。

这样套三个for循环就可以暴力枚举结果了

//伪代码演示
for (int i = 0; i < n;) // 固定一个数a
{for (int j = i + 1; j < n;)     //依次固定枚举第二个数{for (int k = j + 1; k < n;)    //枚举第三个数{//查找符合的三元组,去重...}}}

 (这里去重在下面双指针解法解释),这里套了三个for循环时间复杂度:O(N³)。

②.  双指针算法

这里双指针算法的解决方法就是:排序+双指针+去重

排序同上面暴力枚举,都先对一整个数组排序,再进行下面的处理。

这里举例一个已经排过序的新数组:

我们先固定一个数,这里先固定第一个数:

这里就转化成了和为s的两个数的问题,这里的s就是这个固定的数的相反数。也就是:

 所以这里解决步骤:

  1. 先对整个数组排序
  2. 固定一个数 a(这里有个小优化,后续介绍)
  3. 在该数后面的区间内,利用双指针算法快速找到两个数的和为 -a 的即可。

注意:这里只是找到了符合条件的情况,并没有去重。

接下来就是处理细节问题了,也就是去重确保所有符合条件的情况不落下(后面简称不漏) 。

和为s的两个数(这里会用到,详细介绍在此链接)

不漏的处理:

先控制指针找到符合情况:

这时可以看到是找到符合的情况了: 接下来就需要调整:

所以,也就是找到一种结果之后,不要停(两个指针不停),缩小区间(两指针都向内移动一步),继续寻找符合的情况。

 去重处理:

去重要考虑两种情况:

  1. 找到一种结果之后,left和right指针要跳过重复的元素(这里也就把第一个4给枚举完了)。但这里固定的 a 还是为-4,再继续枚举,是肯定都是重复结果的。
  2. 所以当使用完一次双指针算法后,a也需要跳过重复的元素。

这里去重可能指针会越界,为了避免越界:

这里的越界问题不止对整个数组区间的越界,还有对要用双指针处理的区间可能会越界。

在实现去重代码时需要加个判断条件就可以解决:

要判断处理这个条件,既可避免越界
if(left < right)        
也就判断两个指针是否在相遇前

 固定一个数 a 的优化:

因为我们前面先排序该数组为升序了,所以固定数a就可以仅仅需要保证它≤0即可。 

if (nums[i] > 0)
{break; // 小优化,数a为正数情况不用考虑,是一定不成立的
}

 接下来实现代码。

3. 代码实现

题目链接:三数之和

Ⅰ.  暴力枚举(会超时 O(N³))

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {// 1.排序sort(nums.begin(), nums.end());vector<vector<int>> ret; // 用来存储所有的三元组// 2.暴力枚举int n = nums.size();int i, j, k;for (i = 0; i < n;) // 固定一个数a{for (j = i + 1; j < n;)     //依次固定枚举第二个数{for (k = j + 1; k < n;)    //枚举第三个数{int sum = nums[i] + nums[j] + nums[k];if (sum == 0){ret.push_back({ nums[i],nums[j],nums[k] });}//去重++k;while (k < n && nums[k] == nums[k - 1]) {++k;}}//去重++j;while (j < n && nums[j] == nums[j - 1]) {++j;}}//去重++i;while (i < n && nums[i] == nums[i - 1]) {++i;}}return ret;}
};

提交记录:

测试用例:

 

 

 

 

Ⅱ.  双指针算法 (O(N²))

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {// 1.排序sort(nums.begin(), nums.end());vector<vector<int>> ret; // 用来存储所有的三元组// 2.利用双指针解决int n = nums.size();for (int i = 0; i < n;) // 固定一个数a{if (nums[i] > 0) {break; // 小优化,数a为正数情况不用考虑,是一定不成立的}// 定义left,right,target通过双指针获取相加等于0的组合int left = i + 1, right = n - 1, target = -nums[i];while (left < right) {int sum = nums[left] + nums[right];if (sum > target) {--right;} else if (sum < target) {++left;} else {// 将获取的三元组尾插ret里ret.push_back({nums[i], nums[left], nums[right]});// 将所有的情况获取--不漏,并去重// 缩小区间查找++left;--right;// 去重left和right,注意区间越界问题while (left < right && nums[left] == nums[left - 1]) {++left;}while (left < right && nums[right] == nums[right + 1]) {--right;}}}// 注意去重i++i;while (i < n && nums[i] == nums[i - 1]) {++i;}}return ret;}
};

注:这里时间复杂度是O(N²)。 

提交记录:

 

 制作不易,若有不足之处或出问题的地方,请各位大佬多多指教 ,感谢大家的阅读支持!!!  

 

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

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

相关文章

98_api_intro_websitetools_sslcertinfo

域名 SSL 证书信息解析 API 数据接口 网络工具&#xff0c;提供域名 SSL 证书信息解析&#xff0c;多信息查询&#xff0c;毫秒级响应。 1. 产品功能 提供域名 SSL 证书信息解析&#xff1b;最完整 SSL 属性信息解析&#xff1b;支持多种元素信息抽取&#xff0c;包括主题的可辨…

抓包工具WireShark使用记录

目录 网卡选择&#xff1a; 抓包流程&#xff1a; 捕获过滤器 常用捕获过滤器&#xff1a; 抓包数据的显示 显示过滤器&#xff1a; 常用的显示过滤器&#xff1a; 实际工作中&#xff0c;在平台对接&#xff0c;设备对接等常常需要调试接口&#xff0c;PostMan虽然可以进…

基于单片机的自动充电蓝牙智能台灯的设计

本设计以单片机为主要控制芯片&#xff0c;主要包括主控模块&#xff0c;显示模块&#xff0c;蓝牙模块&#xff0c;ADC转换信号模块&#xff0c;红外感应模块&#xff0c;光敏模块&#xff0c;充电模块等多功能设计。台灯分为自动模式与手动模式&#xff0c;自动模式开启时&am…

猎板 PCB 专业解读:HDI 技术叠构全解

在现代电子制造领域&#xff0c;HDI&#xff08;高密度互连&#xff09;技术占据着举足轻重的地位。其核心亮点在于极具创新性的叠构设计&#xff0c;这一设计使得电子产品在体积上得以大幅缩减&#xff0c;同时性能也获得显著提升。借助精密的盲埋孔连接工艺&#xff0c;HDI 显…

【卷积基础】CNN中一些常见卷积(1*1卷积、膨胀卷积、组卷积、深度可分离卷积)

文章目录 逐通道卷积&#xff08;Pointwise Convolution&#xff0c;1x1 卷积&#xff09;主要作用逐通道卷积的操作过程优势代码示例典型应用 膨胀卷积&#xff08;Dilated Convolution&#xff09;主要作用工作原理膨胀率 (dilation rate) 的定义代码实例膨胀卷积的优点 组卷…

王道考研之数据结构

数据结构系列 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 数据结构 数据结构系列1.线性表1.1 线性表的定义和相关概念1.2 线性表的创销 增删查改 判空表长打印 2.顺序表2.1 顺序表定义和相关概念2.2 顺序表的静态实现2.3 顺序表的…

Scala 中 set 的实战应用 :图书管理系统

1. 创建书籍集合 首先&#xff0c;我们创建一个可变的书籍集合&#xff0c;用于存储图书馆中的书籍信息。在Scala中&#xff0c;mutable.Set可以用来创建一个可变的集合。 val books mutable.Set("朝花惜拾", "活着") 2. 添加书籍 我们可以使用操作符…

Python venv 虚拟环境 相关 Windows环境 2024 /11/9

Python venv 虚拟环境 相关 年纪大了,好些时候力不从心,这里记录一下,以防忘记! Windows环境 第一次使用 创建 venv myvenv是自定义名字 python -m venv myvenv 激活和启动 前面是路径这里关键词为 activate (激活) myvenv\Scripts\activate 验证是否创建成功 where pytho…

Linux:基于ncdu命令的存储容量自动扫描统计工具

一、背景 设备存储容量不够时&#xff0c;需要删除清理无用文件&#xff0c;若文件目录较多&#xff0c;逐个去统计每个文件目录的存储占用量&#xff0c;比较麻烦。ncdu命令有一个比较好的扫描和删除交互界面&#xff0c;基于ncdu命令写一个定时自动统计脚本&#xff0c;可以…

TSMI252012PMX-2R2MT电子元器件详解

TSMI252012PMX-2R2MT电子元器件详解 一、引言 TSMI252012PMX-2R2MT是一款由深圳市时源芯微科技有限公司&#xff08;TimeSource&#xff09;生产的功率电感器&#xff0c;其设计用于满足现代电子设备的高性能和高可靠性需求。作为电子元件的重要组成部分&#xff0c;功率电感…

Java | Leetcode Java题解之第551题学生出勤记录I

题目&#xff1a; 题解&#xff1a; class Solution {public boolean checkRecord(String s) {int absents 0, lates 0;int n s.length();for (int i 0; i < n; i) {char c s.charAt(i);if (c A) {absents;if (absents > 2) {return false;}}if (c L) {lates;if …

音视频入门基础:FLV专题(23)——FFmpeg源码中,获取FLV文件音频信息的实现(下)

音视频入门基础&#xff1a;FLV专题系列文章&#xff1a; 音视频入门基础&#xff1a;FLV专题&#xff08;1&#xff09;——FLV官方文档下载 音视频入门基础&#xff1a;FLV专题&#xff08;2&#xff09;——使用FFmpeg命令生成flv文件 音视频入门基础&#xff1a;FLV专题…

Python练习13

Python日常练习 题目&#xff1a; 请编写fun函数&#xff0c;其功能是打印杨辉三角形。杨辉三角行如图所示&#xff1a; 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 要求&#xff1a; 采用列表函数完成 -----------------------------------…

Redis - 持久化

Redis ⽀持RDB和AOF两种持久化机制&#xff0c;持久化功能有效地避免因进程退出造成数据丢失问题&#xff0c; 当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。本章内容&#xff1a; 介绍RDB、AOF的配置和运⾏流程&#xff0c;以及控制持久化的命令&#xff0c;如bgsave和…

Vivado+Vscode联合打造verilog环境

一、Vivado下载安装 详细参考我另一篇文章&#xff1a; Vivado2022.2下载安装_fpga vivado下载-CSDN博客https://blog.csdn.net/weixin_61081689/article/details/143460790?spm1001.2014.3001.5501 二、Vscode下载安装 详细参考我另一篇文章&#xff1a; VscodeAnacond…

项目实战使用gitee

1.创建本地仓库 2.进行提交到本地仓库 创建仓库后在idea中会显示图标&#xff0c;点击绿色的√进行快速提交 3.绑定远程仓库 4.番外篇-创建gitee仓库 注意不要勾选其他

Golang | Leetcode Golang题解之第551题学生出勤记录I

题目&#xff1a; 题解&#xff1a; func checkRecord(s string) bool {absents, lates : 0, 0for _, ch : range s {if ch A {absentsif absents > 2 {return false}}if ch L {latesif lates > 3 {return false}} else {lates 0}}return true }

派(分治法)

题目&#xff1a;蒜头君的生日要到了&#xff01;根据习俗&#xff0c;他需要将一些派分给大家。他有 N个不同口味、不同大小的派。 有 F个朋友会来参加我的派对&#xff0c;每个人会拿到一块派&#xff08;必须一个派的一块&#xff0c;不能由几个派的小块拼成&#xff1b;可以…

Docker + Python

文章目录 一、Docker Hub - 使用搜索 Python二、Python Image 使用1、如何使用此 Image在 Python 应用项目中 创建`Dockerfile`文件运行单个 Python 脚本镜像中的多个 Python 版本2、镜像变体1、`python:<version>`2、`python:<version>-slim`3、`python:<versi…

虚拟机linux7.9下安装mysql遇到的问题

1.提示文件权限不够 解决&#xff1a;chmod -R 777 /usr/local/mysql/ 2.提示硬盘空间不够&#xff0c;mysql初始化失败 解决&#xff1a;更改/etc/my.cnf&#xff0c;将日志文件大小减少&#xff08;innodb_log_file_size&#xff09;&#xff0c;删除/data/mysql目录下的文…