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,判断 nums 中是否存在三个元素 a,b,c ,使得 a b c 0 ?找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 给定数组 nums [-1, 0,…...
springboot2集成东方通tongweb嵌入式版
由于最近项目需要国产化信创改造,引入东方通tongweb 联系东方通厂家 ,将依赖导入到maven仓库,并获取嵌入式版license文件修改pom.xml,引入依赖,注意springboot版本,这里以springboot2举例 首先移除springb…...
【二分查找】Leetcode 33. 搜索旋转排序数组【中等】
搜索旋转排序数组 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], num…...
Zephyr Windows开发环境搭建
Zephyr 如果有错误或未及时更新,请以官网文档为主 官网:https://docs.zephyrproject.org/latest/develop/getting_started/index.htm 下载安装 Chocolatey 这是一个类似于在Linux系统下 yum 和 apt 那样的包管理器 官网:https://chocolat…...
如何安全地设置MySQL数据库的IP白名单
设置MySQL数据库的IP白名单是一种关键的安全措施,可以确保只有来自特定IP地址的请求被允许访问数据库服务器。这里是如何安全地配置这些设置的分步指南。 步骤1: 登录到MySQL服务器 首先,使用管理员权限登录到你的MySQL服务器。如果你使用的是命令行&a…...
Chatgpt掘金之旅—有爱AI商业实战篇|品牌故事业务|(十六)
演示站点: https://ai.uaai.cn 对话模块 官方论坛: www.jingyuai.com 京娱AI 一、AI技术创业在品牌故事业务有哪些机会? 人工智能(AI)技术作为当今科技创新的前沿领域,为创业者提供了广阔的机会和挑战。随…...
为什么要部署IP SSL证书?怎么申请?
我们需要知道什么是IP SSL证书。SSL,全称为Secure Sockets Layer,即安全套接层,是为网络通信提供安全及数据完整性的一种安全协议。而IP SSL证书就是基于SSL协议的一种证书,它能够为网站和用户的数据传输提供加密处理,…...
最新免费 ChatGPT、GPTs、AI换脸(Suno-AI音乐生成大模型)
🔥博客主页:只恨天高 ❤️感谢大家点赞👍收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容…...
前端的未来已然到来
随着整个软件行业正逐渐转向以打包、托管与抽象解决方案为主体的新形态,后端与基础设施带来的麻烦正越来越少,而立足堆栈顶部的前端工程师开始成为施展空间最大的时代宠儿。甚至不只是他们,如今无论是前端、后端还是运维开发者,他…...
Open CASCADE学习|gp_XYZ与gp_Mat
gp_XYZ和gp_Mat是Open CASCADE Technology (OCCT)中的类,用于处理3D几何和变换。 gp_XYZ gp_XYZ类代表了一个三维空间中的点或向量。它通过三个坐标值(X, Y, Z)来定义位置或方向。这个类提供了多种操作,比如计算两点之间的距离、…...
BMS绝缘电阻检测原理【转】
...
优秀的测试开发工程师需要掌握哪些技能?
科技的发展与网络技术的广泛应用,让测试开发已成为软件开发过程中不可或缺的一环。测试开发工程师是为确保软件程序的质量和稳定性而工作的专业人士。但是成为一名合格的测试开发工程师需要具备哪些技能呢?一起来看看吧! 优秀的测试开发工程…...
思维树(Tree of Thoughts)的概念
思维树(Tree of Thoughts,简称ToT)是一种利用大型语言模型进行问题解决的框架。这个框架借鉴了人类认知研究的成果,特别是关于人类在做决策时的两种思维方式:快速、自动、无意识的模式(称为“系统1”&#…...
探索设计模式的魅力:抽象工厂模式的艺术
个人主页: danci_ 🔥系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自文章:探索设计模式的魅力:抽象工厂模式的艺术 抽象工厂模式&…...
果园系统养殖游戏喂养偷菜种植浇水养成小程序
装扮 通过购买装扮场景切换不同的农场风格 土地升级 通过特定的材料对土地和房屋进行升级 日志 记录道具的使用数量及金币农作物的收入情况 幸运转盘 可用金币进行抽奖 宝箱开启 获得宝箱后可以通过金币开启 每日签到 每日签到获得奖励 系统公告 可以第一时间知道游戏的更新和…...
Windows版PHP7.4.9解压直用(免安装-绿色-项目打包直接使用)
安装版和解压版 区别 安装版: 安装方便,下一步------下一步就OK了,但重装系统更换环境又要重新来一遍,会特别麻烦解压版(推荐): 这种方式(项目打包特别方便)能更深了解mysql的配置&…...
凡泰极客亮相2024 亚马逊云科技出海全球化论坛,为企业数字化出海赋能
随着「不出海,即出局」登上热搜榜单,企业出海已成燎原之势,3月29日,2024 亚马逊云科技出海全球化论坛在深圳成功举办,凡泰极客创始人梁启鸿受邀出席,并以 「App 2.0:以SuperApp构建智能数字生态…...
新零售门店、商品、会员管理指标体系总览
新零售,旨在打破传统零售业的边界,引入先进科技和数字化手段,通过整合线上线下渠道,全面提升用户体验,并实现更智能、高效、个性化的零售运营模式。这一模式不仅仅关注销售产品,更注重构建全方位的购物生态…...
网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)
网上订餐系统目录 目录 基于springboot的网上订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户功能模块的实现 (1)用户注册界面 (2)用户登录界面 (3)菜品详情界面 (…...
python的抽象类和抽象方法
抽象类是一种不能直接被继承的类。举个例子,我们可以从类Creature衍生出类People,Cats,其中前者两条腿走路,后者四条腿走路,而单独的类Creature却没有一个几条腿走路的方法,因为这是不确定的。 ࿰…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
