题目描述

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. LeetCode 153.Find Minimum in Rotated Sorted Array(M)(P)

    题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...

  2. echarts实现饼图及横向柱状图的绘制

    项目中需要绘制饼图,因此简单学习了下echarts的基本使用.head中引入js文件: <script src="/static/frame/echarts/echarts.min.j ...

  3. 简单服务器端Blazor Cookie身份验证的演示

    为了演示身份验证如何在服务器端 Blazor 应用程序中工作,我们将把身份验证简化为最基本的元素. 我们将简单地设置一个 cookie,然后读取应用程序中的 cookie. 应用程序身份验证 大多数商 ...

  4. Redis系列五 - 哨兵、持久化、主从

    问:骚年,都说Redis很快,那你知道这是为什么吗? 答:英俊潇洒的面试官,您好.我们可以先看一下 关系型数据库 和 Redis 本质上的区别. Redis采用的是基于内存的,采用的是单进程单线程模型 ...

  5. c++第一周测验

    本次得分为:14.00/14.00, 本次测试的提交时间为:2020-03-08, 如果你认为本次测试成绩不理想,你可以选择再做一次. 1 单选(1分) 下面程序片段哪个没错? 得分/总分 A. in ...

  6. 纯django开发博客系统

    企业级教程:纯django开发博客系统 1.视频教程 https://www.duanshuilu.com/ 2.教程文档 https://www.duanshuilu.com/ 0.课程简介1.简价 ...

  7. 为Python安装pip

    Python及操作系统的支持 Python 2.6, 2.7, 3.2, 3.3, 3.4 Unix/Linux, OS X, 以及 Windows   默认包含 Python 2.7.9 及以后的版 ...

  8. C++ 在界面中添加图片

    #include <stdio.h> #include <easyx.h> #include <graphics.h> void huayuan() { Begin ...

  9. 你知道吗,Flutter内置了10多种show

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 showDialog showDialog 用于弹出Mat ...

  10. libfastcommon总结(二)从文件中加载配置信息

    头文件为ini_file_reader.h 主要接口 IniContext iniContext;//定义配置文件信息 iniLoadFromFile();//加载文件为结构化配置信息    iniG ...