每日一题:LeetCode-LCR 007. 三数之和

每日一题系列(day 18)

前言:

🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈

   🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉算法👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长的道路🏇🏇,我们要做的,就是斩妖除魔💥💥,打怪升级!💪💪当然切记不可😈走火入魔😈,每日打怪,拾取经验,终能成圣🙏🙏!开启我们今天的斩妖之旅吧!✈️✈️


题目

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。

示例

在这里插入图片描述
提示

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

解法一暴力枚举

  首先分析题目,题目让我们返回一个或多个不同的三元组,可以不用考虑顺序,但是不能有两组三元组都是相同元素,那么首先我们考虑暴力枚举策略:
  先将数组排个序,以便于更好的查看重复的三元组,之后再使用三层for循环将所有情况都枚举出来,判断是否是符合条件的三元组,如果是,组成一维数组尾插进二维数组res中,当遍历完了之后使用set进行去重即可。

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

在这里插入图片描述

在这里插入图片描述
  测试用例可以通过,但是提交却发现还有三个测试用例跑不过,这时我们就要另想他法了。


解法二双指针解法

  我们还可以在暴力的基础上使用双指针解法,我们首先定住一个值,然后使用双指针来标记另外两个值,定住的值不动,双指针遍历剩下的数组元素,找出所有正确的三元组,尾插进二维数组里,数组遍历完,定值再向右遍历,双指针重置。这样循环上述步骤,就可以得到所有三元组,具体的步骤:

  1、数组元素个数不满三个的直接返回空数组。创建二维数组用来存放三元组,为了更方便识别相同的三元组,我们将数组的值排个序。

  2、固定一个值,在固定值后一个位置设置左指针,最后一个元素下标设为右指针,将固定值使用变量target记录。

  3、而题目要求我们三元组的和为0,也就是要我们固定值和左右指针指向的值和为0,又数组是升序数组,如果target的值大于0了,则左右指针的值肯定也会>0,所以固定值一定要保证小于0。

  4、固定值选取后,开始用双指针对数组剩下的元素进行遍历了,使用变量sum记录下左右指针指向元素的和,用来与target的值进行比较。

  5、如果sum的值要大于target,说明右指针大了,数组为升序数组,则右指针向左移一位,再次进行比较。而如果sum的值小于target,说明左指针小了,将左指针右移一位,再次进行比较。

  6、如果sum的值等于target的值,那么表示此时的左右指针加上固定值,就是一个符合规矩的三元组,将此三元组合并为一个一维数组尾插进二维数组ans数组中。

  7、题目的测试用例说明了不能有重复的三元组出现,那么我们就需要进行去重操作,那么什么情况下才会有重复元素出现呢?
  【1】当固定值不变的时候,左指针的的下一个位置的值和上一个位置的值相等,再次进行比较,就是一个新的三元组,但是这个三元组的值和上一个三元组的值就重复了,不仅左指针如此,右指针也是如此,所以需要将左右指针指向和上一个值不同的值。
  【2】当固定值改变的时候,当数组遍历完,固定值需要更新,如果新固定值的值和原来的值相同,那么这组数据便利出来的三元组就和上组数据便利出来的三元组重复了,所以固定值也需要指向新的不重复的值。

代码演示

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {if(nums.size() < 3)//不满一个三元组return {};vector<vector<int>> ans;//二维数组sort(nums.begin(), nums.end());//将数据进行排序int n = nums.size();for(int i = 0 ; i < n;)//固定一个数,然后使用双指针进行三元组比较{if(nums[i] > 0) break;//target的值若>0,而数组又是升序,则后面的数一定也是大于0的int left = i + 1, right = n - 1, target = -nums[i];//左指针为i的下一个位置,右指针为最后一个位置,target为i位处与左右指针相加进行比较的元素while(left < right){int sum = nums[left] + nums[right];//记录左右指针相加的值if(sum > target) right --;//用sum和target值进行比较,>0时说明右指针太大了else if(sum < target) left ++;//<0,说明左指针太小了else//等于0,是符合条件的三元组{ans.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;//这时上一个i的情况已经全部枚举完了,i指向数组的下一个位置while(i < n && nums[i] == nums[i - 1]) i++;//同理,i的下一个位置和上一个位置传的值如果是相同的,那么就会发生重复的三元组,为了去重,将i自增至于上一个i的值不同的位置}return ans;//返回二维数组}
};

在这里插入图片描述
在这里插入图片描述


  这个双指针解法和我们前面写过的类似,可以先看看这题再来做我们说的这道题,思路就会很清晰了:查找总价格为目标值的两个商品

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

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

相关文章

解决chromebook kabylake安装linux没有声音问题

chromebook kabylake安装arch没有声音&#xff0c;好长时间没有解决&#xff0c;一直用的蓝牙耳机。 今天搜搜帖子解决了&#xff0c; 分享供参考 git clone https://github.com/eupnea-project/chromebook-linux-audiocd chromebook-linux-audio ./setup-audio提示 I Underst…

Shell编程--数组

数组 1.定义数组1.1.普通数组1.2.关联数组1.3.数组常用定义方法 2.使用数组shell数组中"*" 和 "" 区别 1.定义数组 数组也是一种变量&#xff0c;常规变量只能保存一个值&#xff0c;数组可以保存多个值 关联数组跟普通数组的区别&#xff1a; 普通数组&a…

linux高级篇基础理论十一(GlusterFS)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

VS中动态库的创建和调用

VS中动态库的创建和调用 库 ​ 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复用的代码。库的存在形式本质上来说库是一种可执行代码的二进制。 ​ 库有两种&#xff1a;静态库&#xff08;.a、.lib&#xff09;和动态库&#xff08;.so、.dll&#xff09;。所谓静态…

一键操作完整的部署项目流程

目录 一、常见的搭配 二、完整的部署项目流程具体步骤 2.1、安装jdk 安装jdk &#xff1a; 配置环境&#xff1a; 检查是否成功&#xff1a; 2.2、配置tomcat外部访问 下载解压软件 安装tomcat 测试tomcat安装是否成功 2.3、安装MySQL 安装vcc环境 命令输入步骤 安…

应用在热能表领域中的数字温度传感芯片

热能表&#xff0c;是适用于测量在热交换环路中&#xff0c;被称作载热液体的液体所吸收或转换热能的仪器&#xff0c;它由流量传感器、温度传感器和热能积算仪三部分组成。热量表&#xff08;热表&#xff09;又称热能表、热能积算仪&#xff0c;既能测量供热系统的供热量又能…

多模态推荐系统综述:二、特征交互 Fusion

二、Fusion 融合不同的多模态信息&#xff0c;与bridge相比&#xff0c;融合更关注项目之间的多模态内部关系。 它可以灵活地融合不同权重和焦点的多模态信息。 注意机制是应用最为广泛的特征融合。 2.1 粗粒度注意力。 一些模型应用注意力机制在粗粒度级别融合来自多种模式…

ES6笔记总结

首先我们需要了解一下什么是 ECMA&#xff1a; ECMA&#xff08;European Computer Manufacturers Association&#xff09;中文名称为欧洲计算机制造商协会&#xff0c;这 个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际 什么是 ECMAScr…

美易官方《美股一哥争夺战白热化:微软市值一度超越苹果》

随着科技股的持续走高&#xff0c;美股一哥争夺战也愈发激烈。微软和苹果这两家科技巨头之间的市值争夺战更是吸引了全球市场的关注。上周苹果接连被两家华尔街机构下调评级后&#xff0c;微软的市值已经在逼近苹果&#xff0c;挑战苹果的美股最高市值公司地位。 微软和苹果都…

[深度学习]Open Vocabulary Object Detection 部署开放域目标检测模型使用感受

一、Open Vocabulary Object Detection介绍 Open Vocabulary Object Detection (OpenVOD) 是一种新型的目标检测方法&#xff0c;它使用开放词汇的概念来识别和检测图像中的对象。与传统的目标检测方法相比&#xff0c;OpenVOD具有更高的灵活性和可扩展性&#xff0c;因为它允…

K8S集群重新初始化--详细过程

K8S集群重新初始化 0、当前环境1、master节点1.1、在master节点执行下面reset命令&#xff1a;1.2、手动清除配置信息&#xff0c;这一步很关键&#xff1a;1.3、重新引导集群1.4、创建配置目录&#xff0c;并复制权限配置文件到用户目录下&#xff1a;1.5 查看集群状态1.6 安装…

小红书私信组件功能解读,商家如何使用

今年八月&#xff0c;小红书私信组件上新了两大新功能。新功能的出现&#xff0c;无疑为商家与消费者的沟通建联&#xff0c;提供了新的可能。今天我们来针对小红书私信组件功能解读&#xff01; 一、小红书私信组件新功能 这次小红书私信组件上新的两大功能分别是&#xff0c;…

Wargames与bash知识10

Wargames与bash知识10 Bandit Level 17 关卡提示&#xff1a; 主目录中有两个文件&#xff1a;passwords.old和passwords.new。下一级的密码在passwords.new中&#xff0c;是在password.old和password.new之间唯一被更改的行 注意&#xff1a;如果你已经解决了这个级别&…

GEE查看SMAP的L3级土壤水分产品并导出为TIFF

SMAP的L3级产品&#xff0c;时间分辨率为每日&#xff0c;空间分辨率为9KM&#xff0c;到2023年12月2日停止提供。 查看逐日的土壤水分变化 // 设置感兴趣区域&#xff08;Region of Interest&#xff09; var roi ee.FeatureCollection(projects/a-flyllf0313/assets/dacha…

【Spring Cloud】微服务架构演变及微服务架构介绍

文章目录 系统架构演变单体应用架构垂直应用架构分布式架构SOA 架构微服务架构 微服务架构介绍微服务架构的常见问题微服务架构的常见概念服务治理服务调用服务网关服务容错链路追踪 微服务架构的常见解决方案ServiceCombSpringCloudSpring Cloud Alibaba 总结 欢迎来到阿Q社区…

C++ 类访问修饰符

数据封装是面向对象编程的一个重要特点&#xff0c;它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。 一个类可以有多个 public、protected…

探索web技术与低代码开发的融合应用

随着物联网、云计算和人工智能等技术的迅猛发展&#xff0c;现代软件开发正面临着日益增长的需求和复杂性。为了应对这一挑战&#xff0c;一种被称为低代码开发的快速、可视化开发方法逐渐崭露头角。本文将探讨低代码开发与web技术的融合应用&#xff0c;以及这种趋势对软件开发…

答题小程序源码系统:自带流量主广告位+视频激励广告 带完整的代码安装包以及搭建教程

随着互联网的迅速发展&#xff0c;各种应用程序层出不穷&#xff0c;而答题类小程序由于其独特的互动性和吸引力&#xff0c;成为了当前最热门的应用之一。答题小程序源码系统是一款基于微信小程序开发的源代码系统&#xff0c;它具有丰富的功能和灵活的定制性&#xff0c;可以…

git修改最新提交(commit)信息

一、修改最近一次commit信息 1、首先通过git log查看commit信息 2、使用命令git commit --amend进入命令命令模式&#xff0c;按i进入编辑模式&#xff0c;修改好commit信息后按Esc键退出编辑模式&#xff0c;然后输入:wq保存编辑信息&#xff08;注意使用英文输入法&#xf…

读书分享-《认知觉醒》揭示心智潜能的启迪之作

《认知觉醒》是一部引人入胜的作品&#xff0c;它不仅深入探索了认知科学的最新进展&#xff0c;而且还以独特的视角阐述了如何通过提升认知能力来改善个人生活和工作效率。作者在书中巧妙地将复杂的科学理论转化为易于理解的语言&#xff0c;使得普通读者也能轻松掌握这些概念…