Leetcode的AC指南 —— 哈希法/双指针:15. 三数之和

摘要:
Leetcode的AC指南 —— 15. 三数之和。题目介绍:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

文章目录

  • 一、题目
  • 二、解析
    • 1、哈希法
    • 2、双指针
  • 3、思考

一、题目


题目介绍
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
力扣题目链接

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1][-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0

示例 2:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0

提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

二、解析


1、哈希法

public static List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();Arrays.sort(nums); // 对数组排序// 找出a + b + c = 0// a = nums[i], b = nums[j], c = -(a + b)for (int i = 0; i < nums.length; i++) {if (nums[i] > 0) {break;}// 对a去重if (i > 0 && nums[i] == nums[i - 1]) {continue;}Set<Integer> set = new HashSet<>();for (int j = i + 1; j < nums.length; j++) {// 对b去重, 由于存在b == c,所以在对b去重时,排除nums = [-1,-1,0,1,-4,0,2,2,2,2]这种情况,避免出现两次【-4,2,2】if (j > i + 2 && nums[j] == nums[j - 1] && nums[j - 1] == nums[j - 2]) {continue;}// 如果set中存在c,则将a,b,c存入result// 如果set中不存在c,添加c到setint c =  - (nums[i] + nums[j]);if (set.contains(c)) {result.add(Arrays.asList(nums[i], nums[j], c));set.remove(c); // 对c去重复} else {set.add(nums[j]);}}}return result;}
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(n),额外的 set 开销

2、双指针

动画效果如下:
在这里插入图片描述

public static List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();Arrays.sort(nums); // 对数组排序int right, left;// a + b + c = 0for(int i = 0; i < nums.length - 2; i++){if(nums[i] > 0 || nums[nums.length - 1] < 0) break; // 最小值大于0,最大值小于0时,不满足题意,直接跳出循环if(i > 0 && nums[i] == nums[i - 1]) continue; // 对a去重复left = i + 1; // 左指针指向a后的第一个元素right = nums.length - 1; // 右指针指向数组的最后一个元素while (left < right) {int sum = nums[i] + nums[left] + nums[right];if (sum > 0) {right--;} else if (sum < 0) {left++;} else {result.add(Arrays.asList(nums[i], nums[left], nums[right]));// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重while (right > left && nums[right] == nums[right - 1]) right--; // 左移指针,指向第一个相邻不重复的元素右侧while (right > left && nums[left] == nums[left + 1]) left++; // 右移指针,指向第一个相邻不重复的元素的左侧right--; // 右指针指向第一个相邻不重复的元素left++; // 左指针指向第一个相邻不重复的元素/*while (right > left) {right--;if(nums[right] != nums[right + 1]) break;} // 左移指针,指向第一个相邻不重复的元素while (right > left && nums[left] == nums[left - 1]) left++; // 右移指针,指向第一个相邻不重复的元素*/}}}return result;}
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(1)

3、思考


两数之和可以用双指针法吗?

答: 是不可以的。两数之和要求返回数组索引下标,而双指针法要求排序,一旦排序后,原数组的索引下标就改变了。如果两数之和也是返回数值的话,就可以使用双指针了。

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

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

相关文章

数据加密、端口管控、行为审计、终端安全、整体方案解决提供商

PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是关于这几个概念的解释&#xff1a; 数据加密&#xff1a;这是一种通过加密算法和密钥将明文转换为密文&#xff0c;以及通过解密算法和解密密钥将密文恢复为明文…

《新传奇》期刊投稿论文发表

《新传奇》杂志是经国家新闻出版总署批准、面向国内外公开发行的综合性社科期刊&#xff0c;由湖北省文联主管&#xff0c;湖北今古传奇传媒集团有限公司主办&#xff0c;湖北优秀期刊。本刊旨在坚守初心、引领创新&#xff0c;展示高水平研究成果&#xff0c;支持优秀学术人才…

Python+Yolov5+Qt交通标志特征识别窗体界面相片视频摄像头

程序示例精选 PythonYolov5Qt交通标志特征识别窗体界面相片视频摄像头 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonYolov5Qt交通标志特征识别窗体界面相片视频摄像头》编写代码&a…

vue 拖拽通过子元素拖拽父元素指令

vue 拖拽通过子元素拖拽父元素指令 需求 拖拽头部 拖动整个框 // candrag.js中的代码如下 directive // 通过子元素 控制移动父元素&#xff0c; 如果 需要直接控制父元素可以再写一个自定义指令 或者改造下这个指令 export default {// 定义 Vue 插件install(Vue) {Vue.di…

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理

深入浅出图解C#堆与栈 C# HeapingVS Stacking第二节 栈基本工作原理 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](https://mp.cs…

前后端分离nodejs+vue医院预约挂号系统6nrhh

医院预约挂号系统主要有管理员、用户和医生三个功能模块。以下将对这三个功能的作用进行详细的剖析。 运行软件:vscode 前端nodejsvueElementUi 语言 node.js 框架&#xff1a;Express/koa 前端:Vue.js 数据库&#xff1a;mysql 开发软件&#xff1a;VScode/webstorm/hbuiderx均…

Unity Meta Quest 一体机开发(十二):【手势追踪】Poke 交互 - 用手指点击由 3D 物体制作的 UI 按钮

文章目录 &#x1f4d5;教程说明&#x1f4d5;给玩家配置 HandPokeInteractor&#x1f4d5;用 3D 物体制作可以被点击的 UI 按钮⭐搭建物体层级⭐给物体添加脚本⭐为脚本变量赋值 &#x1f4d5;模仿官方样例按钮的样式&#x1f4d5;在按钮上添加文字&#x1f4d5;修改按钮图片 …

十大开放式蓝牙耳机品牌榜单,不同价位高能推荐!购前必看!

作为一个在耳机圈混迹多年的老油条&#xff0c;近期用的最多的耳机就是开放式耳机&#xff0c;我用过的开放式耳机不能说数不胜数&#xff0c;但我使用过的开放式耳机的款式和品牌肯定是比大多数人要多的多&#xff0c;对于开放式耳机也是有颇深的了解&#xff0c;我可以告诉你…

【23.12.29期--Spring篇】Spring的 IOC 介绍

介绍一下Spring的IOC ✔️引言✔️ lOC的优点✔️Spring的IOC✔️ 拓展知识仓✔️IOC是如何实现的&#xff1f; ✔️引言 所谓的IOC (inversion of control) &#xff0c;就是控制反转的意思。何为控制反转? 在传统的程序设计中&#xff0c;应用程序代码通常控制着对象的创建和…

FME之读取文件名路径FilenamePartExtractor转换器

在读取文件所在路径及相关信息时&#xff0c;我们除了在读模块时选择Directory and File Pathnames数据类型。还可以选择在某个阶段使用FilenamePartExtractor转换器来读取文件所在路径及相关信息。 在前面转换器只要暴露有fme_dataset&#xff0c;在源文件名选择它即可实现。…

nodejs+vue+ElementUi农产品团购销售系统zto2c

目标是为了完成小区团购平台的设计和实现&#xff0c;在疫情当下的环境&#xff0c;方便小区业主购入生活所需&#xff0c;减小居民的生活压力 采用B/S模式架构系统&#xff0c;开发简单&#xff0c;只需要连接网络即可登录本系统&#xff0c;不需要安装任何客户端。开发工具采…

SAP问题 OPEN SQL 取不到值

关键&#xff1a;数据库中有数据&#xff0c;但是open sql取不到数据 背景&#xff1a; 标准程序在测试环境正常执行&#xff0c;在生产环境报错。 解决过程&#xff1a; 第一步&#xff1a;分析执行结果不一致可能的原因&#xff1a; 1.测试数据问题&#xff0c;可能性小&…