题目描述

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. Jira字段配置最佳实践

    在我们创建Jira时,Jira上会填写各式各样的字段,不同的字段对于不同的角色人员,使用方式也是不同的,通过这篇文章,希望大家能够对Jira使用有更深刻的认识. 为什么需要严格规范? 易于开发,测试, ...

  2. jvm GC算法和种类

    1.GC     垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟 ...

  3. ZOJ 4109 Welcome Party

    题目链接:(https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370504)(https://vjudge.net/proble ...

  4. 总结:利用asp.net core日志进行生产环境下的错误排查(asp.net core version 2.2,用IIS做服务器)

    概述 调试asp.net core程序时,在输出窗口中,在输出来源选择“调试”或“xxx-ASP.NET Core Web服务器”时,可以看到类似“info:Microsoft.AspNetCore. ...

  5. c:\Windows\system32\rundll32.exe Windows无法访问指定设备、路径或文件,你可能没有适当的权限访问该项目

    非常懂如何修改权限的可以尝试,否则老老实实地重新注册的系统的.dll文件 重新注册方法如下: WIN+R下输入命令: cmd /c for %i in (%windir%\system32\*.dll ...

  6. 编写程序实现输入x,y,判断属于第几象限。

    x = float(input("请输入横坐标:")) y = float(input("请输入纵坐标:")) if x > 0 and y > 0 ...

  7. JAVAEE学习day04方法的定义和重载

    1.方法定义的格式 方法就是完成特定功能的代码块 修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2...){ 方法体; return 返回值; } 修饰符: 初学者只需记住publ ...

  8. js 实现简单的导航下拉列表

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 从源码看 PHP 7 数组的实现

    本文所用源码为 PHP 7.4.4 的版本. PHP 7 数组概述 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当 ...

  10. Hadoop集群搭建(七)~完全分布运行模式

    我使用的是完全分布运行模式.上一篇安装了JDK,本篇记录Hadoop的安装,版本2.7.2 (一)配置文件 1,先将hadoop安装包解压到module目录下 2,配置hadoop-env.sh.vi ...