题目描述

1. 三数之和

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

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:

[[-1, 0, 1],[-1, -1, 2]]

题目解析

  1. 要求a + b + c = 0 ==> a + b = -c
  2. 数组无序且存在重复元素,但是结果中不可以包含重复的三元组
  3. 可能没有满足条件的情况,返回空数组

方法一:暴力法

解题思路

采用三层循环的方式,最外层循环固定一个元素 nums[i] ,第二层循环从元素 nums[i]下一个元素 j = i + 1,nums[j] 开始遍历,第三层循环则从元素 nums[j]下一个元素 k = j + 1,nums[k] 开始遍历,然后判断三个元素相加是否满足以下条件:nums[i] + nums[j] + nums[k] == 0

代码示例

Java:

public List<List<Integer>> threeSum(int[] nums) {
if (nums == null || nums.length <= 2) {
return new ArrayList<List<Integer>>();
}
Arrays.sort(nums);
Set<List<Integer>> result = new LinkedHashSet<>();
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
List<Integer> value = Arrays.asList(nums[i], nums[j], nums[k]);
result.add(value);
}
}
}
}
return new ArrayList<>(result);
}

复杂度分析

时间复杂度:O(n^3)

空间复杂度:O(1)

方法二:哈希表

解题思路

题目要求为a + b + c = 0可以推出 a + b = -c ,将三数之和转化为两数求和的问题。外层循环固定某个元素 nums[i] ,然后再剩下的元素中找到两个元素相加等于-nums[i]的情况。

代码示例

Java:

public List<List<Integer>> threeSum(int[] nums) {
if (nums == null || nums.length <= 2) {
return new ArrayList<List<Integer>>();
} Set<List<Integer>> result = new LinkedHashSet<>();
for (int i = 0; i < nums.length - 2; i++) {
int target = -nums[i];
Map<Integer, Integer> hashMap = new HashMap<>(nums.length - i);
for (int j = i + 1; j < nums.length; j++) {
int v = target - nums[j];
Integer exist = hashMap.get(v);
if (exist != null) {
List<Integer> list = Arrays.asList(nums[i], exist, nums[j]);
list.sort(Comparator.naturalOrder());
result.add(list);
} else {
hashMap.put(nums[j], nums[j]);
}
}
}
return new ArrayList<>(result);
}

复杂度分析

时间复杂度:O(n^2)

空间复杂度:O(n)

方法二:双指针法

解题思路

有方法二中可以得知 a + b = -c,在外层循环中固定元素 nums[i] ,然后再剩余元素中找到两元素相加和为-nums[i]的情况。此时若将数组元素有序,则可通过双指针的方式进行元素遍历,加快元素查找。

数组有序,若nums[i]>0,则后续数组元素必大于零,不可能满足条件;否则使用双指针l=i+1和r=len-1遍历数组剩余元素;

nums[l]+nums[r]+nums[i] > 0 则高位指针r向中间移动,否则低位指针l向中间移动;

nums[l]+nums[r]+nums[i] = 0 则通过判断l、r指针与其前/后元素是否相同加速指针移动。

代码示例

Java:

public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums == null || nums.length <= 2) {
return res;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int l = i + 1, r = nums.length - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
if ( sum == 0) {
res.add(Arrays.asList(nums[i],nums[l],nums[r]));
while (l<r && nums[l] == nums[++l]);
while (l<r && nums[r] == nums[--r]);
} else if (sum < 0) {
l++;
} else if (sum > 0) {
r--;
}
}
}
return res;
}

复杂度分析

时间复杂度:O(n^2)

空间复杂度:O(1)

【LeetCode】15.三数之和的更多相关文章

  1. LeetCode 15. 三数之和(3Sum)

    15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...

  2. Java实现 LeetCode 15 三数之和

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

  3. LeetCode——15. 三数之和

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

  4. LeetCode 15. 三数之和(3Sum)

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

  5. [Leetcode 15]三数之和 3 Sum

    [题目] Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? ...

  6. [LeetCode]15. 三数之和(数组)(双指针)

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

  7. [LeetCode] 15. 三数之和

    题目链接:https://leetcode-cn.com/problems/3sum/ 题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a ...

  8. LeetCode:三数之和【15】

    LeetCode:三数之和[15] 题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的 ...

  9. 代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和

    第一题454.四数相加II 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, ...

  10. leetcode题目15.三数之和(中等)

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

随机推荐

  1. Jstorm执行task报错windows CONFIG SET protected-mode no

    windows  CONFIG SET protected-mode no报错说redis受保护模式,redis使用的是Redis-x64-3.2.100,参考博文说是redis3.2之后加入的特性, ...

  2. 关于CSS居中问题的一些总结

    前端页面开发中关于内容居中的需求应用概率很大,自己搜集一些资料和总结关于css里的几种居中效果实现 第一常用text-align:center先将子元素将块级元素改为行内元素,即display:inl ...

  3. 37个JavaScript基本面试问题和解答

    1.使用typeof bar ==="object"来确定bar是否是一个对象时有什么潜在的缺陷?这个陷阱如何避免? 尽管typeof bar ==="object&qu ...

  4. win10查看本机mac地址的详细操作

    今天和大家分享win10查看本机mac地址的方法,mac地址是什么东西?MAC地址实际上就是网卡的一个标识,和身份证号码类似,大多数情况下是不需要关心MAC地址是多少的,一般不能改动,所以也不会重复. ...

  5. 解决layui表单ajax提交回调函数不起作用问题的两种方式

    最近想用layui开发一个论坛模板用的是fly-ui,才接触layui对其还不太熟悉.一个简单的登录就困扰了我很久.登录的form通过ajax提交回调函数老是不起作用.经过浪费了N多时间的调试,发现l ...

  6. JAVA有关位运算的全套梳理

    一.在计算机中数据是如何进行计算的? 1.1:java中的byte型数据取值范围 我们最开始学习java的时候知道,byte类型的数据占了8个bit位,每个位上或0或1,左边第一位表示符号位,符号位如 ...

  7. 必备技能七、Vuex

    这段时间一直在用vue写项目,vuex在项目中也会依葫芦画瓢使用,但是总有一种朦朦胧胧的感觉.于是决定彻底搞懂它. 看了一下午的官方文档,以及资料,才发现vuex so easy! 作为一个圈子中的人 ...

  8. iview中遇到table的坑(已经修改了table的数据,但是界面没有更新)

    https://blog.csdn.net/bigdargon/article/details/89381466 https://blog.csdn.net/qiuyan_f/article/deta ...

  9. 基于springcloud搭建项目-公共篇(二)

    上一篇已经写过如何搭建注册中心eureka,这一篇主要是搭建一些公共的api接口服务,并把实体类单独拿出来放到一个服务上引用,比较简单的 1.首先.创建一个实体类服务,这样就不用在每个服务里创建实体了 ...

  10. TARS基金会:构建微服务开源生态

    导语 在20世纪60至70年代,软件开发人员通常在大型机和小型机上使用单体架构进行软件开发,没有一个应用程序能够满足大多数最终用户的需求.垂直行业使用的软件代码量更小,与其他应用程序的接口更简单,而可 ...