当前位置: 首页 > news >正文

LeetCode-15-三数之和问题

题目说明

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。

给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

题目分析

这个问题比起两数之和来,显然要复杂了一些,而且由于结果可能有多种情况,还要考虑去重,整体难度提升了不少。
最后的返回,就不再是一个简单的数组了,而是“数组的数组”,每一组解都是一个数组,最终有多组解都要返回。

解题方法

方法一:暴力法

最简单的办法,当然还是暴力法。基本思路是,每个人都先去找到另一个人,然后再一起逐个去找第三个人。
很容易想到,实现起来就是三重循环:这个时间复杂度是 O(n^3)。

下面展示一些 内联代码片

    public List<List<Integer>> threeSum(int[] nums) {int n = nums.length;List<List<Integer>> resultList = new ArrayList<>();
// 三重循环,遍历所有的三数组合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 ){resultList.add(Arrays.asList(nums[i], nums[j], nums[k]));}}}}return resultList;}

运行一下,我们会发现,这个结果其实是不正确的没有去重,同样的三元组在结果中无法排除。比如-1,0,1会出现两次。而且时间复杂度非常高,是N^3。
所以接下来,我们就要做一些改进,试图降低时间复杂度,而且解决去重问题。

暴力法的改进:结果去重

要做去重,自然首先想到的,就是把结果保存到一张hash表里。仿照两数之和,直接存到HashMap里查找,代码如下:

    public List<List<Integer>> threeSum(int[] nums) {int n = nums.length;List<List<Integer>> result = new ArrayList<>();Map<Integer, List<Integer>> hashMap = new HashMap<>();// 遍历数组,寻找每个元素的thatNumfor( int i = 0; i < n; i++ ){int thatNum = 0 - nums[i];if( hashMap.containsKey(thatNum) ){List<Integer> tempList = new ArrayList<>(hashMap.get(thatNum));tempList.add(nums[i]);result.add(tempList);continue;}for( int j = 0; j < i; j++ ){int newKey = nums[i] + nums[j];if( ! hashMap.containsKey(newKey) ){List<Integer> tempList = new ArrayList<>();tempList.add(nums[j]);tempList.add(nums[i]);hashMap.put( newKey, tempList );}}}return result;}

方法二 双指针法

思路解析
暴力法搜索时间复杂度为O(N^3),要进行优化,可通过双指针动态消去无效解来提高效率。
双指针的思路,又分为左右指针和快慢指针两种。
我们这里用的是左右指针。左右指针,其实借鉴的就是分治的思想,简单来说,就是在数组头尾各放置一个指针,先让头部的指针(左指针)右移,移不动的时候,再让尾部的指针(右指针)左移:最终两个指针相遇,那么搜索就结束了。

(1)双指针法铺垫: 先将给定 nums 排序,复杂度为 O(NlogN)。
首先,我们可以想到,数字求和,其实跟每个数的大小是有关系的,如果能先将数组排序,那后面肯定会容易很多。
之前我们搜索数组,时间复杂度至少都为O(N^2),而如果用快排或者归并,排序的复杂度,是 O(NlogN),最多也是O(N^2)。所以增加一步排序,不会导致整体时间复杂度上升。

public List<List<Integer>> threeSum(int[] nums){int n = nums.length;List<List<Integer>> result = new ArrayList<>();// 先对数组进行排序Arrays.sort(nums);for( int i = 0; i < n; i++ ){if( nums[i] > 0 )break;if( i > 0 && nums[i] == nums[i-1] )continue;// 定义左右指针(索引位置)int lp = i + 1;int rp = n - 1;// 只要左右不重叠,就继续移动指针while( lp < rp ){int sum = nums[i] + nums[lp] + nums[rp];if( sum == 0 ){result.add(Arrays.asList(nums[i], nums[lp], nums[rp]));lp ++;rp --;while( lp < rp && nums[lp] == nums[lp - 1] )lp ++;while( lp < rp && nums[rp] == nums[rp + 1] )rp --;}else if( sum < 0 )lp ++;elserp --;}}return result;}

复杂度分析:
时间复杂度 O(N^2):其中固定指针k循环复杂度 O(N),双指针 i,j 复杂度 O(N)。比暴力法的O(n^3),显然有了很大的改善。
空间复杂度 O(1):指针使用常数大小的额外空间。

尽管时间复杂度依然为O(n^2),但是过程中避免了复杂的数据结构,空间复杂度仅为常数级O(1),可以说,双指针法是一种很巧妙、很优雅的算法设计。

相关文章:

LeetCode-15-三数之和问题

题目说明 给定一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;找出所有满足条件且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 给定数组 nums [-1, 0,…...

springboot2集成东方通tongweb嵌入式版

由于最近项目需要国产化信创改造&#xff0c;引入东方通tongweb 联系东方通厂家 &#xff0c;将依赖导入到maven仓库&#xff0c;并获取嵌入式版license文件修改pom.xml&#xff0c;引入依赖&#xff0c;注意springboot版本&#xff0c;这里以springboot2举例 首先移除springb…...

【二分查找】Leetcode 33. 搜索旋转排序数组【中等】

搜索旋转排序数组 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], num…...

Zephyr Windows开发环境搭建

Zephyr 如果有错误或未及时更新&#xff0c;请以官网文档为主 官网&#xff1a;https://docs.zephyrproject.org/latest/develop/getting_started/index.htm 下载安装 Chocolatey 这是一个类似于在Linux系统下 yum 和 apt 那样的包管理器 官网&#xff1a;https://chocolat…...

如何安全地设置MySQL数据库的IP白名单

设置MySQL数据库的IP白名单是一种关键的安全措施&#xff0c;可以确保只有来自特定IP地址的请求被允许访问数据库服务器。这里是如何安全地配置这些设置的分步指南。 步骤1: 登录到MySQL服务器 首先&#xff0c;使用管理员权限登录到你的MySQL服务器。如果你使用的是命令行&a…...

Chatgpt掘金之旅—有爱AI商业实战篇|品牌故事业务|(十六)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业在品牌故事业务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随…...

为什么要部署IP SSL证书?怎么申请?

我们需要知道什么是IP SSL证书。SSL&#xff0c;全称为Secure Sockets Layer&#xff0c;即安全套接层&#xff0c;是为网络通信提供安全及数据完整性的一种安全协议。而IP SSL证书就是基于SSL协议的一种证书&#xff0c;它能够为网站和用户的数据传输提供加密处理&#xff0c;…...

最新免费 ChatGPT、GPTs、AI换脸(Suno-AI音乐生成大模型)

&#x1f525;博客主页&#xff1a;只恨天高 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容…...

前端的未来已然到来

随着整个软件行业正逐渐转向以打包、托管与抽象解决方案为主体的新形态&#xff0c;后端与基础设施带来的麻烦正越来越少&#xff0c;而立足堆栈顶部的前端工程师开始成为施展空间最大的时代宠儿。甚至不只是他们&#xff0c;如今无论是前端、后端还是运维开发者&#xff0c;他…...

Open CASCADE学习|gp_XYZ与gp_Mat

gp_XYZ和gp_Mat是Open CASCADE Technology (OCCT)中的类&#xff0c;用于处理3D几何和变换。 gp_XYZ gp_XYZ类代表了一个三维空间中的点或向量。它通过三个坐标值&#xff08;X, Y, Z&#xff09;来定义位置或方向。这个类提供了多种操作&#xff0c;比如计算两点之间的距离、…...

BMS绝缘电阻检测原理【转】

...

优秀的测试开发工程师需要掌握哪些技能?

科技的发展与网络技术的广泛应用&#xff0c;让测试开发已成为软件开发过程中不可或缺的一环。测试开发工程师是为确保软件程序的质量和稳定性而工作的专业人士。但是成为一名合格的测试开发工程师需要具备哪些技能呢&#xff1f;一起来看看吧&#xff01; 优秀的测试开发工程…...

思维树(Tree of Thoughts)的概念

思维树&#xff08;Tree of Thoughts&#xff0c;简称ToT&#xff09;是一种利用大型语言模型进行问题解决的框架。这个框架借鉴了人类认知研究的成果&#xff0c;特别是关于人类在做决策时的两种思维方式&#xff1a;快速、自动、无意识的模式&#xff08;称为“系统1”&#…...

探索设计模式的魅力:抽象工厂模式的艺术

个人主页: danci_ &#x1f525;系列专栏&#xff1a;《设计模式》《MYSQL应用》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自文章&#xff1a;探索设计模式的魅力&#xff1a;抽象工厂模式的艺术 抽象工厂模式&…...

果园系统养殖游戏喂养偷菜种植浇水养成小程序

装扮 通过购买装扮场景切换不同的农场风格 土地升级 通过特定的材料对土地和房屋进行升级 日志 记录道具的使用数量及金币农作物的收入情况 幸运转盘 可用金币进行抽奖 宝箱开启 获得宝箱后可以通过金币开启 每日签到 每日签到获得奖励 系统公告 可以第一时间知道游戏的更新和…...

Windows版PHP7.4.9解压直用(免安装-绿色-项目打包直接使用)

安装版和解压版 区别 安装版: 安装方便&#xff0c;下一步------下一步就OK了&#xff0c;但重装系统更换环境又要重新来一遍&#xff0c;会特别麻烦解压版&#xff08;推荐&#xff09;&#xff1a; 这种方式&#xff08;项目打包特别方便&#xff09;能更深了解mysql的配置&…...

凡泰极客亮相2024 亚马逊云科技出海全球化论坛,为企业数字化出海赋能

随着「不出海&#xff0c;即出局」登上热搜榜单&#xff0c;企业出海已成燎原之势&#xff0c;3月29日&#xff0c;2024 亚马逊云科技出海全球化论坛在深圳成功举办&#xff0c;凡泰极客创始人梁启鸿受邀出席&#xff0c;并以 「App 2.0&#xff1a;以SuperApp构建智能数字生态…...

新零售门店、商品、会员管理指标体系总览

新零售&#xff0c;旨在打破传统零售业的边界&#xff0c;引入先进科技和数字化手段&#xff0c;通过整合线上线下渠道&#xff0c;全面提升用户体验&#xff0c;并实现更智能、高效、个性化的零售运营模式。这一模式不仅仅关注销售产品&#xff0c;更注重构建全方位的购物生态…...

网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)

网上订餐系统目录 目录 基于springboot的网上订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户功能模块的实现 &#xff08;1&#xff09;用户注册界面 &#xff08;2&#xff09;用户登录界面 &#xff08;3&#xff09;菜品详情界面 &#xff08…...

python的抽象类和抽象方法

抽象类是一种不能直接被继承的类。举个例子&#xff0c;我们可以从类Creature衍生出类People&#xff0c;Cats&#xff0c;其中前者两条腿走路&#xff0c;后者四条腿走路&#xff0c;而单独的类Creature却没有一个几条腿走路的方法&#xff0c;因为这是不确定的。 &#xff0…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...