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却没有一个几条腿走路的方法,因为这是不确定的。 ࿰…...
ARMv8、AArch64 与 arm64:命名与体系结构要点
ARMv8、AArch64 与 arm64:命名与体系结构要点 ARMv8 指 ARM 架构的一个主版本代际;AArch64 是该代际下的 64 位执行状态与 A64 指令集;arm64 与 aarch64 是操作系统与工具链中对 AArch64 的常用三元组/目录名,二进制约定一致。下…...
在对话中处理生物特征(指纹、虹膜)时,OpenClaw 的识别精度?
关于OpenClaw在生物特征识别上的精度,其实很难给出一个绝对的数字。这倒不是因为技术本身有什么神秘之处,而是因为精度这个指标,在实际应用中常常被误解了。 很多人一提到识别精度,脑子里立刻会冒出一个百分比,比如99.…...
Matlab 实现 DES 与 RSA 双重加密及可视化界面搭建
基于matlab上的DES和RSA两种算法的双重加密,附带显示界面,可更改DES密钥,明文消息(在显示界面中),可在代码中更改RSA对应的p,q,e等数据,代码可附加注释和对应要求修改。在…...
FRCRN模型结构解析:频域卷积+循环网络如何协同提升信噪比
FRCRN模型结构解析:频域卷积循环网络如何协同提升信噪比 1. 引言:语音降噪的挑战与突破 语音降噪技术一直面临着"既要又要"的难题:既要彻底消除背景噪声,又要完整保留人声细节。传统的降噪方法往往在这两者之间难以平…...
STM32标准库项目如何用VSCode一键编译下载?详解tasks.json与Makefile的联动配置
STM32标准库项目在VSCode中实现一键编译下载的终极指南 1. 为什么选择VSCode进行STM32开发? 传统嵌入式开发往往依赖于Keil、IAR等商业IDE,但这些工具存在几个明显痛点: 高昂的授权费用:商业IDE的许可证价格让个人开发者和小团队望…...
RWKV7-1.5B-g1a保姆级部署教程:离线加载+免外网依赖,中小企业AI落地首选
RWKV7-1.5B-g1a保姆级部署教程:离线加载免外网依赖,中小企业AI落地首选 1. 模型简介 rwkv7-1.5B-g1a 是基于新一代 RWKV-7 架构的多语言文本生成模型,专为中小企业AI落地场景优化设计。这个1.5B参数的轻量级模型在保持高质量生成能力的同时…...
Blazor组件测试工具:BootstrapBlazor测试库完整指南
Blazor组件测试工具:BootstrapBlazor测试库完整指南 【免费下载链接】BootstrapBlazor 项目地址: https://gitcode.com/gh_mirrors/bo/BootstrapBlazor BootstrapBlazor测试库是企业级Blazor UI组件库的质量保障体系,提供了一套完整的组件测试解…...
RustFS集群部署避坑指南:我用Ansible踩过的3个坑及解决方案
RustFS集群部署实战:Ansible自动化中的三大典型问题与深度解决方案 当你在凌晨三点收到集群告警通知时,会不会希望当初的部署方案能更健壮些?作为经历过数十次生产环境部署的老兵,我想分享那些官方文档不会告诉你的实战经验。本文…...
OpenClaw技能扩展指南:为GLM-4.7-Flash添加自定义功能
OpenClaw技能扩展指南:为GLM-4.7-Flash添加自定义功能 1. 为什么需要自定义技能 去年冬天,当我第一次尝试用OpenClaw自动整理电脑上的照片时,发现现有的技能库无法满足我的特殊需求——按照拍摄地点和人物自动分类。这让我意识到࿰…...
ES核心索引机制深度解析:从“正排”与“倒排”的底层原理到实战应用场景
1. 正排索引与倒排索引的本质区别 第一次接触Elasticsearch时,我被"正排"和"倒排"这两个概念绕得头晕。直到有次做商品搜索功能,才真正理解它们的差异。想象你面前有两本电话簿:一本按人名排序(正排ÿ…...
