15 三数之和(2021-07-09)
15. 三数之和
链接:https://leetcode-cn.com/problems/3sum/
题目描述见链接内容。
解法1:三重循环+HasH去重
想不到什么好的思路,于是就笨方法开干,用三种循环来进行比较,用一个HasH来保存已有的结果,用结果的前两个数字做key
,够暴力
var threeSum = function (nums) {const len = nums.length;if (len < 3) {return [];}const hash = {},result = [];for (let i = 0; i < len; i++) {for (let j = i + 1; j < len; j++) {for (let k = j + 1; k < len; k++) {if (nums[i] + nums[k] + nums[j] === 0) {const temp = [nums[i], nums[k], nums[j]].sort((prev, next) => prev - next),key = `${temp[0]}-${temp[1]}`;if (!hash[key]) {result.push(temp);hash[key] = true;}}}}}return result;
};
- 时间复杂度:
${O(N^3)}$
- 空间复杂度:
${O(N)}$
- 执行用时:不出所料的超时了
解法2:三重循环+排序
下面跟着官方题解进行优化,首先优化HasH去重的问题,可以先把数组从小到大排序,这样当我们找到一个符合要求的数组[-1, 0, 1]
,[0, -1, 1]
这一类重复的数组就不会再被找到
另外,对于每一重循环而言,如果相邻两次枚举的元素相同,那么结果也是重复的,例如[0, 1, 2, 2]
,找到[0, 1, 2]
后,第三重循环继续走的话,找到的还是[0, 1, 2]
,所以需要对相邻两次枚举值的元素相同进行去重
var threeSum = function (nums) {const len = nums.length,sorted = nums.sort((a, b) => a - b);if (len < 3) {return [];}const result = [];for (let i = 0; i < len; i++) {const first = sorted[i];if (i > 0 && first === sorted[i - 1]) {continue;}for (let j = i + 1; j < len; j++) {const second = sorted[j];if (j > i + 1 && second === sorted[j - 1]) {continue;}for (let k = j + 1; k < len; k++) {const third = sorted[k];if (k > j + 1 && third === sorted[k - 1]) {continue;}if (first + second + third === 0) {result.push([sorted[i], nums[k], nums[j]]);}}}}return result;
};
- 时间复杂度:
${O(N^3)}$
- 空间复杂度:
${O(1)}$
- 执行用时:仍然超时
解法3:排序 + 双指针
上面仍然需要三重循环,在优化的方法就是利用双指针,因为已经对数组进行了排序,那么在一种循环中固定一个基数x
后,第二轮循环可以同时去找到第二个数和第三个数
声明两个指针start
和end
,start
指向二重循环的起点,end
指向终点,nums[start]
一定小于nums[end]
,我们的目标就是找到nums[start]
加上nums[end]
等于-x
的情况,分情况讨论:
nums[start] + nums[end] < -x
,这时候将start
向右移动一位,让nums[start]
变大,继续寻找nums[start] + nums[end] > -x
,这时候将end
向左移动一位,让nums[end]
变小,继续寻找nums[start] + nums[end] === -x
,这时候就是我们要找到的情况,存起来,并且将start
和end
同时向内收缩,要注意的时还要注意去重,去重只能在这种情况才需要,如果nums[start]
和nums[start - 1]
相等,那么结果一定是重复的,所以需要将start
继续增大,end
同理
var threeSum = function (nums) {const len = nums.length,sorted = nums.sort((a, b) => a - b);if (len < 3) {return [];}const result = [];for (let i = 0; i < len; i++) {const first = sorted[i];if (first > 0) {return result;}if (i > 0 && first === sorted[i - 1]) {continue;}let start = i + 1,end = len - 1;while (start < end) {const second = sorted[start],third = sorted[end],target = -first;const temp = second + third;if (temp > target) {end -= 1;} else if (temp < target) {start += 1;} else {result.push([first, second, third]);end -= 1;start += 1;// start 重复元素while (start < end && sorted[start] === sorted[start - 1]) {start += 1;}// end 重复元素while (start < end && sorted[end] === sorted[end + 1]) {end -= 1;}}}}return result;
};
- 时间复杂度:
${O(N^2)}$
- 空间复杂度:
${O(1)}$
- 执行用时:124ms, 在所有JavaScript提交中击败了100%的用户,内存消耗:47.6MB,在所有JavaScript提交中击败了91%的用户
15 三数之和(2021-07-09)相关推荐
- 代码随想录算法训练营第07天 | LeetCode 454.四数相加2,383. 赎金信,15. 三数之和,18. 四数之和,总结
LeetCode [454. 四数相加 II] 题目:给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足 ...
- (补)算法训练第七天|力扣454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和
代码随想录算法训练营第七天|力扣454.四数相加II ,383. 赎金信,15. 三数之和,18. 四数之和 454.四数相加II 题目链接:四数相加II 参考:https://programmerc ...
- Leetcode python《热题 HOT 100》15. 三数之和
Leetcode python 之 <热题 HOT 100>:https://leetcode-cn.com/problemset/hot-100/ 15. 三数之和 给定一个包含 n 个 ...
- 15. 三数之和 golang
15. 三数之和 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意:答案中不 ...
- LeetCode 15. 三数之和(3Sum)
15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...
- [双指针|模拟] leetcode 15 三数之和
[双指针|模拟] leetcode 15 三数之和 1.题目 题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? ...
- Suzy找到实习了吗Day 7 | 哈希表结束啦 454. 四数相加 II,383. 赎金信,15. 三数之和,18. 四数之和
454. 四数相加 II(dict hash) 题目 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足 ...
- 代码随想录算法训练营第七天| 哈希表理论基础 ,454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和
代码随想录算法训练营第七天| 哈希表理论基础 ,454.四数相加II, 383. 赎金信, 15. 三数之和, 18. 四数之和 454.四数相加II 建议:本题是 使用map 巧妙解决的问题,好好体 ...
- 【LeetCode 算法】15.三数之和
15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[ ...
最新文章
- html弹窗赋值给查询框,bootstrap模态框动态赋值, ajax异步请求数据后给id为queryInfo的模态框赋值并弹出模态框(JS)...
- python中datetime模块常用方法_Python中datetime的使用和常用时间处理
- Android:面试官死亡问答,如何优化一个网络请求?大牛多个网络优化方案帮你解决!
- grabcut.cpp:380: error: (-215) !bgdSamples.empty() !fgdSamples.empty() in function initGMMs
- 静态库符号文件冲突的解决办法,已实践OK, mark
- SSL与HTTPS,HTTP有什么联系
- HP 520 双系统 vista xp
- 超详细Ubuntu Linux安装配置 Tomcat
- API数据安全知多少【知识篇】
- Where do SAP CRM HANA Live Querys come from
- c#使用System.Windows.Forms.DataVisualization.Charting.dll绘制图表实例
- 不要讨厌HATEOAS Part Deux:HATEOAS的春天
- 一个完整的使用的例子,和可下代码
- Xcode打包后,找不到dSYM文件
- vue html if,vue中v-if使用方法详解
- 浅谈Web大数据可视化平台开发流程
- Java 17的这些新特性,Java迈入新时代
- 【计算机组成原理】计算机系统结构笔记:合集
- N1 从 armbian 刷回 webpad 方法
- 怎样调整计算机显示屏窗口,怎么调整电脑窗口的大小