[LeetCode三数之和] | 刷题打卡
一直有刷题习惯,最近才看到掘金举办了刷题活动,特来参加!此题为第8题。不得不说掘金的主题就是漂亮呀!赞。
本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
描述
给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。结果不能包含重复的三元组。
例1:
输入:[2,7,11,15]
输出:[]
例2:
输入:[-1,0,1,2,-1,-4]
输出:[[-1, 0, 1],[-1, -1, 2]]
二、思路分析:
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|
| 双指针法 | 相向双指针 | ||
| 第一步 | 排序,假设 a <= b <= c | ||
| 第二步 | for 循环 ,查找等于a的两数之和 ,找 b + c = -a 即可调用 two sum 的算法来解决。 |
三、AC 代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
* @lc app=leetcode.cn id=15 lang=java
*
* [15] 三数之和
*/
// @lc code=start
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
// fix bug i < nums.length ,not result.size
for (int i = 0; i < nums.length; i++) {
if (i != 0 && nums[i] == nums[i - 1]) {
continue;
}
findTwoNum(nums, i, result);
}
return result;
}
private void findTwoNum(int[] nums, int index, List<List<Integer>> result) {
// why [left+1,length-1]
// finaly nums[left+1-1]==nums[left+]
int left = index + 1;
int right = nums.length-1;
int target = -nums[index];
while (left < right) {
int sum = nums[left] + nums[right];
if (sum < target) {
left++;
} else if (sum > target) {
right--;
} else {
// sum = target
List<Integer> list = new ArrayList();
list.add(nums[index]);
list.add(nums[left]);
list.add(nums[right]);
// result.add
result.add(list);
left++;
right--;
// nums[index]==nums[index+1]
while (left < right && nums[left] == nums[left - 1]) {
left++;
}
}
}
}
}
// @lc code=end
四、总结:
这已经是第8道两数之和类的问题了,从第1道题看过来的朋友,已经能够很迅速反应出来这题考察啥了,此题正是第8道使用双指针可以快速解决的题目。
这道题主要是锻炼做题者换元的思想,举一反三的能力,两数之和和三数之和有什么区别?
答:没有区别。
两数之和是给定target和nums[i]找寻符合条件的nums[j]
三数之和如何换元呢?a + b + c = 0变形为 b + c= - a
引申一下
a + b + c = 3如何做呢?b + c= 3 - a