每日一题: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;//返回二维数组}
};
这个双指针解法和我们前面写过的类似,可以先看看这题再来做我们说的这道题,思路就会很清晰了:查找总价格为目标值的两个商品
相关文章:

每日一题:LeetCode-LCR 007. 三数之和
每日一题系列(day 18) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🔎…...
四元数傅里叶变换(Quaternion Fourier Transforms) 在信号和图像处理中的应用
引言: 信号和图像处理是现代科学和工程领域中非常重要的一个方向,它涉及到对信号和图像进行分析、压缩、增强和恢复等操作。传统的信号和图像处理方法主要依赖于傅里叶变换和滤波器等工具,但这些方法在处理复杂系统时存在一定的局限性。近年来,四元数傅里叶变换作为一种新兴…...

vue项目之.env文件.env.dev、test、pro
.env文件是vue运行项目时的环境配置文件。 .env: 全局默认配置文件,所有环境(开发、测试、生产等)均会加载并合并该文件 .env.development(开发环境默认命名) 开发环境的配置,文件名默认为.env.development,如果需要改名也是可以的…...

Fabric2.2:在有系统通道的情况下搭建应用通道
写在最前 在使用Fabric-SDK-Go1.0.0操作Fabric网络时遇到了bug。Fabric-SDK-GO的当前版本没有办法在没有系统通道的情况下创建应用通道,而Fabric的最新几个版本允许在没有系统通道的情况下搭建应用通道。为了解决这个矛盾并使用Fabric-SDK-GO完成后续的项目开发&…...
测试人员必备基本功(2)
容易被忽视的bug 第二章 修改表单容易被忽视的bug 文章目录 容易被忽视的bug第二章 修改表单容易被忽视的bug 前言一、修改表单二、具体功能1.修改角色2.接口设计 三、测试设计1.测试点2.容易发现bug的测试点如下: 总结 前言 一个WEB系统的所有功能模块࿰…...

第十二章 Java内存模型与线程(一)
文章目录 12.3 Java内存模型12.3.1 主内存与工作内存12.3.2 内存间交互操作小结12.3.3 对于volatile型变量的特殊规则12.3.5 原子性、可见性与有序性12.3.6 先行发生原则 12.3 Java内存模型 12.3.1 主内存与工作内存 1.Java 内存模型规定了所有的变量都存储在主内存ÿ…...

C# WPF 数据绑定
需求 后台变量发生改变,前端对应的相关属性值也发生改变 实现 接口 INotifyPropertyChanged 用于通知客户端(通常绑定客户端)属性值已更改。 示例 示例一 官方示例代码如下 using System; using System.Collections.Generic; using System.ComponentModel; using Sys…...

进程和线程的比较
目录 一、前言 二、Linux查看进程、线程 2.1 Linux最大进程数 2.2 Linux最大线程数 2.3 Linux下CPU利用率高的排查 三、线程的实现 四、上下文切换 五、总结 一、前言 进程是程序执行相关资源(CPU、内存、磁盘等)分配的最小单元,是一…...

深入理解 Flink(四)Flink Time+WaterMark+Window 深入分析
Flink Window 常见需求背景 需求描述 每隔 5 秒,计算最近 10 秒单词出现的次数 —— 滑动窗口 每隔 5 秒,计算最近 5 秒单词出现的次数 —— 滚动窗口 关于 Flink time 种类 TimeCharacteristic ProcessingTimeIngestionTimeEventTime WindowAssign…...

科技创新领航 ,安川运动控制器为工业自动化赋能助力
迈入工业4.0时代,工业自动化的不断发展,让高精度运动控制成为制造业高质量发展的重要技术手段。北京北成新控伺服技术有限公司作为一家集工业自动化产品销售、系统设计、开发、服务于一体的高新技术企业,其引进推出的运动控制产品一直以卓越的…...

图像异或加密及唯密文攻击
异或加密 第一种加密方式为异或加密,异或加密的原理是利用异或的可逆性质,原始图像的像素八位bit分别与伪随机二进制序列异或,得到的图像就为加密图像。如下图对lena图像进行加密。 伪随机序列为一系列二进制代码,它受加密秘钥控…...
React Grid Layout基础使用
摘要 React Grid Layout是一个用于在React应用程序中创建可拖拽和可调整大小的网格布局的库。它提供了一个灵活的网格系统,可以帮助开发人员构建响应式的布局,并支持拖拽、调整大小和动画效果。本文将介绍如何使用React Grid Layout来创建自适应的布局。…...
第11章 1 文件及IO操作
文章目录 文件的概述及基本操作步骤 p151文件的写入操作 p152文件的读取操作及文件复制 p153文件的读取操作文件复制 with语句的使用 p154一维数据和二维数据的存储与读取 p155高维数据的存储和读取 p156os模块中的常用的函数 p157os.path模块中常用的函数 p158 文件的概述及基…...
Tomcat服务实例部署
目录 **Tomcat 由一系列的组件构成,其中核心的组件有三个:** 什么是 servlet? 什么是 JSP? Tomcat 功能组件结构: Container 结构分析: Tomcat 请求过程: ## Tomcat 服务部署 1.关闭防火墙…...

高精度彩色3D相机:开启崭新的彩色3D成像时代
3D成像的新时代 近年来,机器人技术的快速发展促使对3D相机技术的需求不断增加,原因在于,相机在提高机器人的性能和实现多种功能方面发挥了决定性作用。然而,其中许多应用所需的解决方案更复杂,仅提供环境的深度信息是…...

借助Gitee将typora图片上传CSDN
概述 前面已经发了一个如何借助Github将typora上的图片上传到csdn上,但这有个缺陷:需要科学上网才能加速查看已经上传到github上的图片,否则就会出现已经上传的图片,无法正常查看的问题 如何解决? 那就可以使用Gite…...
几件奇怪的事产生的疑团
1.记得当年在中国科技大学杨照华给我们上初等数论课(杨是北大毕业,闵嗣鹤教授的关门弟子,后来到华南师大任教),他说过“据华老(华罗庚)讲,希尔伯特最先解决华林问题的论文中用到二十…...

陶瓷碗口缺口检测-图像增强
图像增强 在采集图像的过程中,可能会有由于采集图像环境中光源照射不足,导致采集的图像对比度不足,图像视觉效果较暗的情况,可以通过直方图均衡化或者直方图规定化。如图a为原图像对比度低,图c为其直方图,…...

gitee创建远程仓库并克隆远程仓库到电脑
1、首先点加号新建一个仓库 2、输入仓库名,路径会自动填充,填写简单的仓库介绍,先选择私有,在仓库创建之后,可以改为开源 3、打开建好的仓库 4、复制仓库链接 5、打开一个文件夹(想要存储远程仓库的地址),在…...

3D人体姿态估计(教程+代码)
3D人体姿态估计是指通过计算机视觉和深度学习技术,从图像或视频中推断出人体的三维姿态信息。它是计算机视觉领域的一个重要研究方向,具有广泛的应用潜力,如人机交互、运动分析、虚拟现实、增强现实等。 传统的2D人体姿态估计方法主要关注通…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

Spring AOP代理对象生成原理
代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】,这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
【大厂机试题解法笔记】矩阵匹配
题目 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式 N M K N*M矩阵 输…...

20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决
20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决 2025/6/7 17:20 缘起: 1、根据RK809的DATASHEET,短按开机【100ms/500ms】/长按关机,长按关机。6s/8s/10s 我在网上找到的DATASHE…...