双指针(7)_单调性_三数之和

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

双指针(7)_单调性_三数之和

收录于专栏【经典算法练习
本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接:

2.题目描述 :

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

    代码展示 :

    结果分析 :

    解法二(排序 + 双指针) :

    算法思路 :

    图解流程 :

    代码展示 :

    结果分析 :

    4.总结 :


1. 题目链接:

OJ链接----. - 力扣(LeetCode)

2.题目描述 :

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

1. 对整个数组进行排序

2. 三层循环遍历数组

3. 使用set去重 

    代码展示 :

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {set<vector<int>> T;sort(nums.begin(), nums.end());int n = nums.size();for(int i = 0; i < n - 2; i++)for(int j = i + 1; j < n; j++)for(int k = j + 1; k < n; k++){if(nums[i] + nums[j] + nums[k] == 0) {T.insert({nums[i], nums[j], nums[k]});}}vector<vector<int>> result(T.begin(), T.end());return result;}
};

 

    结果分析 :

由于数据范围是3000,所以我们这个三层循环就算有了排序的优化,也没能通过(只差5个例子), 

    解法二(排序 + 双指针) :

这里大家可以先去看查找总价格为目标值的两个商品这道题,那道题与本题思路很像

--双指针(6)_单调性_查找总价格为目标值的两个商品-CSDN博客

    算法思路 :

本题与两数之和类似,是非常经典的面试题

与两数之和稍微不同的是,题目中要求找到所有[不重复]的三元组.那我们可以利用在两数之和那里用的双指针思想,来对我们的暴力枚举做优化:

        i. 先排序

        ii. 然后固定一个数a:

        iii. 在这个数后面的区间内,使用双指针算法快速找到两个数之和等于-a即可

但是要注意的是,这道题需要有[去重]操作~

        i. 找到一个结果之后,left和right指针要[跳过重复]的元素

        ii. 当使用完一次双指针算法之后,固定a也要[跳过重复]的元素

    图解流程 :

开始我们就对数组进行排序,这样数组中的序列就是单调有序的,这样我们就可以使用双指针进行求解问题!!!

 

 固定一个数,剩下的数构成二元组,然后在二元组里面利用双指针进行寻找

如果left + right < -dest

说明right左边所有数加left都小于dest

那么left就无需遍历,left++

 

如果left + right > -dest

说明left右边所有数加right都大于dest

那么right就无需遍历,right--

 

如果left + right == -dest

说明找到题目符合条件的数,插入到vector

left++,right--

 

注意:(去重问题)

这里也是left + right == -dest

说明找到题目符合条件的数,插入到vector

left++,right--

但是这里要判断nums[left - 1] == nums[left] 如果相等left直接++

nums[right] == nums[right - 1] 如果相等直接--

 

 

进行去重处理后left指向1, right也指向1

此时left + right < -dest lest++

left < right(不满足)循环结束

dest++

 

dest++的小优化: 

当dest大于0时:

循环可以直接结束,因为我们的数组已经排序

left和right也一定是大于0的

 

去重的边界问题

left 和right:

它们两个去重时,可能会访问到未定义的内存,需要进行条件束缚

left < right

dest:

它在去重时也可能会访问到未定义的内存,也需要进行条件束缚\

dest < nums.size()

 

    代码展示 :

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

 

    结果分析 :

顺利通过!!!
这道题很有价值,虽然难度是中等,但已经逼近困难了!

这道的思路其实不难(其实就是之前双指针(6)中那题一样的思想),它难的地方就在于如何去重,在去重的过程中是否会注意到一些细节问题!

    4.总结 :

 这道题使用的是排序 + 双指针算法

1. 排序:

2. 固定一个数a:

3. 在该数后面的区间内,利用双指针算法快速找到两个的和等于-a即可

处理细节问题:

1. 去重

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

        当使用完一次双指针算法之后,i也需要跳过重复元素

2. 不漏

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

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

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

相关文章

Redis 常用命令总结

文章目录 目录 文章目录 1 . 前置内容 1.1 基本全局命令 KEYS EXISTS ​编辑 DEL EXPIRE TTL TYPE 1.2 数据结构和内部编码 2. String类型 SET GET MGET MSET SETNX INCR INCRBY DECR DECYBY INCRBYFLOAT 命令小结 内部编码 3 . Hash 哈希类型 HSET …

gpt4最新保姆级教程

如何使用 WildCard 服务注册 Claude3 随着 Claude3 的震撼发布&#xff0c;最强 AI 模型的桂冠已不再由 GPT-4 独揽。Claude3 推出了三个备受瞩目的模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 以及 Claude 3 Opus&#xff0c;每个模型都展现了卓越的性能与特色。其中&a…

数据结构基本知识

一、什么是数据结构 1.1、组织存储数据 ---------》内存&#xff08;存储&#xff09; 1.2、研究目的 如何存储数据&#xff08;变量&#xff0c;数组....)程序数据结构算法 1.3、常见保存数据的方法 数组&#xff1a;保存自己的数据指针&#xff1a;是间接访问已经存在的…

【Vue】pnpm创建Vue3+Vite项目

初始化项目 &#xff08;1&#xff09;cmd切换到指定工作目录&#xff0c;运行pnpm create vue命令&#xff0c;输入项目名称后按需安装组件 &#xff08;2&#xff09;使用vs code打开所创建的项目目录&#xff0c;Ctrl~快捷键打开终端&#xff0c;输入pnpm install下载项目…

[概率论] 随机变量的分布函数 (一)

文章目录 1.随机变量的分布函数2.离散型随机变量的分布函数3.连续性随机变量的分布函数 1.随机变量的分布函数 设X XX是一个随机变量&#xff0c;x xx是任意实数&#xff0c;则函数 几何表示 性质&#xff08;一个函数是分布函数的充要条件&#xff09; 2.离散型随机变量的分布…

数据结构-图-存储-邻接矩阵-邻接表

数据结构-图-存储 邻接矩阵 存储如下图1,图2 图1 对应邻接矩阵 图2 #include<bits/stdc.h> #define MAXN 1005 using namespace std; int n; int v[MAXN][MAXN]; int main(){cin>>n;for(int i1;i<n;i){for(int j1;j<n;j){cin>>v[i][j];}}for(int…

深度解析Unix系统的基本概念及优缺点和原理

介绍 Unix系统是一种多用户、多任务、分时操作系统&#xff0c;起源于20世纪70年代初&#xff0c;由贝尔实验室开发。它具有强大的命令行接口和层次结构的文件系统&#xff0c;支持多种处理器架构&#xff0c;广泛应用于工程应用和科学计算等领域。 基本概念 一、Unix系统的起…

数学建模强化宝典(13)M-K检验法

前言 M-K检验法&#xff0c;全称为Mann-Kendall检验法&#xff0c;是一种非参数的假设检验方法&#xff0c;广泛应用于时间序列数据的趋势性变化检验&#xff0c;特别是气候序列中的趋势分析和突变点检测。以下是对M-K检验法的详细介绍&#xff1a; 一、定义与背景 M-K检验法由…

嵌入式初学-C语言-数据结构--四

栈 1. 基本概念 栈是一种逻辑结构&#xff0c;是特殊的线性表。特殊在&#xff1a; 只能在固定的一端操作 只要满足上述条件&#xff0c;那么这种特殊的线性表就会呈现一种“后进先出”的逻辑&#xff0c;这种逻辑就被称为栈。栈 在生活中到处可见&#xff0c;比如堆叠的盘子…

Kubernetes部署(haproxy+keepalived)高可用环境和办公网络打通

HAProxy Keepalived 部署高可用性入口&#xff1a; 部署两台或多台节点运行 HAProxy 作为负载均衡器。使用 Keepalived 实现 VIP&#xff08;虚拟 IP&#xff09;&#xff0c;为 HAProxy 提供高可用性。Keepalived 会监控 HAProxy 的状态&#xff0c;如果主节点失效&#xff0…

Spring AOP,通知使用,spring事务管理,spring_web搭建

spring AOP AOP概述 AOP面向切面编程是对面向对象编程的延续&#xff08;AOP &#xff08;Aspect Orient Programming&#xff09;,直译过来就是 面向切面编程,AOP 是一种编程思想&#xff0c;是面向对象编程&#xff08;OOP&#xff09;的一种补充。&#xff09; 面向切面编…

【C++二分查找】1482. 制作 m 束花所需的最少天数

本文涉及的基础知识点 C二分查找 LeetCode1482. 制作 m 束花所需的最少天数 给你一个整数数组 bloomDay&#xff0c;以及两个整数 m 和 k 。 现需要制作 m 束花。制作花束时&#xff0c;需要使用花园中 相邻的 k 朵花 。 花园中有 n 朵花&#xff0c;第 i 朵花会在 bloomDay…

南京网站设计手机用的网站

近年来&#xff0c;随着移动互联网的快速发展&#xff0c;越来越多的用户通过手机浏览网页&#xff0c;这使得网站设计逐渐向移动端倾斜。在南京&#xff0c;网站设计特别注重适配手机端&#xff0c;这不仅是用户体验的提升&#xff0c;也是市场竞争的需要。一个响应式的网站能…

vue3 v-bind=“$attrs“ 的一些理解,透传 Attributes相关说明及事例说明

1、可能小伙伴们经常会在自己的项目中看到v-bind"$attrs"&#xff0c;这个一般是在自定义组件中看到。 比如&#xff1a; <template><BasicModalv-bind"$attrs"register"registerModal":title"getTitle"ok"handleSubm…

Python进程间网络远程通讯方式:socket、pipe、RPC详解!

背景 最近在进行开发工作的时候&#xff0c;遇到了一个场景&#xff1a; pc程序需要和安卓设备进行通讯和接口调用。 此时就需要进行远程调用方法。然而大学时代有关于远程过程调用的知识都还给了老师……所以在此进行一个复习&#xff0c;并进行实战演练&#xff01; 网络…

UE驻网失败问题(三)

这个问题是lab问题&#xff0c;现象如下&#xff1a; 期望UE注册在SA网络下&#xff0c;咋一看没有5G MIB/SIB1打印&#xff0c;好像是没搜到5G小区&#xff0c;而实际上并不是这样。 在查看搜网过程时会发现如下log打印&#xff1a; [I nr5g_rrc_acq.c 3544] RRC ACQ: Band 41…

一个全面、先进、公平且模块化的开源RAG框架

两个关键问题限制了 RAG 的发展&#xff1a; 新型 RAG 算法之间缺乏全面和公平的比较。 像 LlamaIndex 和 LangChain 这样的开源工具使用了高级抽象&#xff0c;这导致了透明度的缺失&#xff0c;并限制了开****发新算法和评估指标的能力。 RAGLAB&#xff1a;是一个模块化的…

QML学习三:qml设计器报错 Line: 0: The Design Mode requires a valid Qt kit

开发环境:Qt 6.5.3 LTS 1、Qt 6.5.3 LTS 2、Pyside6 3、Python 3.11.4 4、win11 默认不打开设计器的时候可以看到我们默认是有Python的环境,而且点击运行是可以运行的。但是当打开qml设计器时提示下面这个错误,提示需要一个可用的套件。 解决办法: 点击+号创建新的套件…

OpenAI官宣ChatGPT用户破2亿,新模型比GPT-4强100倍!

在刚刚召开的“KDDI SUMMIT 2024”大会上&#xff0c;OpenAI日本首席执行官長崎忠雄表示&#xff0c;截止至今年8月底&#xff0c;ChatGPT的月活用户数量突破2亿大关&#xff0c;成为史上最快达到这一成就的软件产品。 同时&#xff0c;ChatGPT企业级用户也获得大幅度增长达到…

Windows自动化程序开发指南

自动化程序的概念 “自动化程序”指的是通过电脑编程来代替人类手工操作的一类程序或软件。这类程序具有智能性高、应用范围广的优点&#xff0c;但是自动化程序的开发难度大、所用技术杂。 本文对自动化程序开发的各个方面进行讲解。 常见的处理对象 自动化程序要处理的对…