前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【LeetCode - 015】三数之和

【LeetCode - 015】三数之和

作者头像
周三不加班
发布于 2019-09-03 02:15:47
发布于 2019-09-03 02:15:47
34600
代码可运行
举报
文章被收录于专栏:程序猿杂货铺程序猿杂货铺
运行总次数:0
代码可运行

题目

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets.
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
 [-1, 0, 1],
 [-1, -1, 2]
]

翻译

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

分析

每次从数组中选出一个数k。从剩下的数中求目标等于target-k的2sum问题。这里须要注意的是有个小技巧:当我们从数组中选出第i数时,我们仅仅须要求数值中从第i+1个到最后一个范围内字数组的2sum问题。   

我们以选第一个和第二个举例。如果数组为A[],总共同拥有n个元素A1。A2….An。非常显然,当选出A1时,我们在子数组[A2~An]中求目标位target-A1的2sum问题,我们要证明的是当选出A2时,我们仅仅须要在子数组[A3~An]中计算目标位target-A2的2sum问题,而不是在子数组[A1,A3~An]中。   证明例如以下:如果在子数组[A1,A3~An]目标位target-A2的2sum问题中,存在A1 + m = target-A2(m为A3~An中的某个数),即A2 + m = target-A1。这刚好是“对于子数组[A3~An],目标位target-A1的2sum问题”的一个解。

即我们相当于对满足3sum的三个数A1+A2+m = target反复计算了。

因此为了避免反复计算,在子数组[A1,A3~An]中,能够把A1去掉,再来计算目标是target-A2的2sum问题。   对于本题要求的求最接近解,仅仅须要保存当前解以及当前解和目标的距离,如果新的解更接近,则更新解。算法复杂度为O(n^2);

代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.ArrayList;import java.util.Arrays;import java.util.LinkedList;import java.util.List;public class Solution {    /**
    * Sum(三个数的和)
    *
    * @param nums 输入的数组
    * @return 运行结果
    */
   public List<List<Integer>> threeSum(int[] nums) {
       List<List<Integer>> result = new LinkedList<>();        if (nums != null && nums.length > 2) {            // 先对数组进行排序
           Arrays.sort(nums);            // i表示如果取第i个数作为结果
           for (int i = 0; i < nums.length - 2; ) {                // 第二个数可能的起始位置
               int j = i + 1;                // 第三个数可能是结束位置
               int k = nums.length - 1;                while (j < k) {                    // 如果找到满足条件的解
                   if (nums[j] + nums[k] == -nums[i]) {                        // 将结果加入到结果含集中
                       List<Integer> list = new ArrayList<>(3);
                       list.add(nums[i]);
                       list.add(nums[j]);
                       list.add(nums[k]);
                       result.add(list);                        // 移动到下一个位置。找下一组解
                       k--;
                       j++;                        // 从左向右找第一个与之前处理的数不同的数的下标
                       while (j < k && nums[j] == nums[j - 1]) {
                           j++;
                       }                        // 从右向左找第一个与之前处理的数不同的数的下标
                       while (j < k && nums[k] == nums[k + 1]) {
                           k--;
                       }
                   }                    // 和大于0
                   else if (nums[j] + nums[k] > -nums[i]) {
                       k--;                        // 从右向左找第一个与之前处理的数不同的数的下标
                       while (j < k && nums[k] == nums[k + 1]) {
                           k--;
                       }
                   }                    // 和小于0
                   else {
                       j++;                        // 从左向右找第一个与之前处理的数不同的数的下标
                       while (j < k && nums[j] == nums[j - 1]) {
                           j++;
                       }
                   }
               }                // 指向下一个要处理的数
               i++;                // 从左向右找第一个与之前处理的数不同的数的下标
               while (i < nums.length - 2 && nums[i] == nums[i - 1]) {
                   i++;
               }
           }
       }        return result;
   }
}

执行结果

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员啊粥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【每天一道编程系列-2018.3.6】(Ans)
【题目描述】 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find
yesr
2019/03/14
3380
No.015 3Sum
15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium   Given an array S of n
mukekeheart
2018/02/27
6360
【LeetCode】(No.015)三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
PM小王
2019/07/02
3350
【LeetCode刷题】:双指针篇(三数之和,四数之和)
题目的意思是给了我们一个数组nums,让我们找出三个下标不相同的数nums[i],nums[j],nums[k],要求这三个数的和恰好等于,然后返回这三个数
爱喝兽奶的熊孩子
2025/01/22
1261
【LeetCode刷题】:双指针篇(三数之和,四数之和)
​LeetCode刷题实战259:较小的三数之和
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/05/28
2870
【刷穿 LeetCode】16. 最接近的三数之和(中等)
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。
宫水三叶的刷题日记
2021/02/20
3280
【leetcode刷题】T2-3Sum
昨天分享了2sum,今天分享leetcode第2篇文章,第15题—3sum,地址是:https://leetcode.com/problems/3sum/
木又AI帮
2019/07/17
3780
双指针高频面试题:「三数之和」的姐妹篇 ...
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。
宫水三叶的刷题日记
2021/02/26
2970
LeetCode-15.三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
悠扬前奏
2020/06/22
3520
【leetcode】15:三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
帅地
2019/06/06
5340
Leetcode打卡 | No.015 三数之和
欢迎和小詹一起定期刷leetcode,每周一和周五更新一题,每一题都吃透,欢迎一题多解,寻找最优解!这个记录帖哪怕只有一个读者,小詹也会坚持刷下去的!
小小詹同学
2018/07/24
7000
Leetcode打卡  |  No.015 三数之和
LeetCode通关:数组十七连,真是不简单
数组基本上是我们最熟悉的数据结构了,刚会写“Hello World”不久,接着就是“杨辉三角”之类的练习。
三分恶
2021/08/10
4090
你真的会做 2 Sum 吗?
我在之前的刷题视频里说过,大家刷题一定要吃透一类题,为什么有的人题目做着越来越少,有的人总觉得刷不完的题,就是因为没有分类吃透。
五分钟学算法
2020/08/21
3950
你真的会做 2 Sum 吗?
LeetCode 259. 较小的三数之和(固定一点,内层双指针)
给定一个长度为 n 的整数数组和一个目标值 target,寻找能够使条件 nums[i] + nums[j] + nums[k] < target 成立的三元组 i, j, k 个数(0 <= i < j < k < n)。
Michael阿明
2020/07/13
1.1K0
哈希——15. 三数之和
示例 1: 输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
向着百万年薪努力的小赵
2022/12/02
2210
Array相关LeetCode题目笔记
Array相关LeetCode题目笔记 11. 盛最多水的容器 题目描述: 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 说明:你不能倾斜容器。 示例 1: 输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。
晓果冻
2022/09/08
1720
leetcode 15. 三数之和
注意:这里要固定一个最左的指针K,可以理解为从[i,j]范围里面选出两个值相加为K指针指向值的相反数 K每次往后移动一次,[i,j]范围都会缩小一个单元 代码:
大忽悠爱学习
2021/11/15
3650
leetcode 两数之和、三数之和、最接近的三数之和、四数之和
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 最容易想到的方法是用一个双重循环来枚举数组中两两组合的情况,然后判断和是否为 target ,时间复杂度是 O(n^2)。 我们还可以先对数组元素从小到大升序排序,然后在一个循环中利用头尾指针扫描排序后的数组,每次扫描比较两个数的和和 target 的值。因为需要得到元素的排序前下标,所以用一个结构体数组来保存数组元素的值和未排序之前元素所在下标,这样的话采用快速排序,时间复杂度为 O(n*logn),空间复杂度为 O(n)。
指点
2019/01/18
2.8K0
三数之和(leetcode15)
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
Vincent-yuan
2021/02/02
5710
前端学数据结构与算法(十二):有趣的算法 - 多指针与滑动窗口
如果说如何用算法高效有趣的解决某些问题,那多指针和滑动算法绝对是算其中的佼佼者。这也是笔者最初接触算法时觉得最有意思的一点,因为解决的问题是熟悉的,但配方却完全不同,本章我们从一个简单的交集问题出发,一步步的认识到多指针及滑动窗口解决某些问题时的巧妙与高效,本章主要以解LeetCode里高频题为参考~
飞跃疯人院
2020/11/19
6180
相关推荐
【每天一道编程系列-2018.3.6】(Ans)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验