1. 题目原址
https://leetcode.com/problems/3sum/
2. 题目描述
3. 题目大意
给定一个数组,返回所有三个数相加和为0的序列
4. 解题思路
- 首先将数组排序
- 如果当前元素大于0,那么就不能存在三个数的和为0的序列,直接返回null即可。
- 为了保证不加入重复的 list,因为是有序的,所以如果和前一个元素相同,只需要继续后移就可以
- i==0,正常寻找另两个数;i>0且当前元素不同于前一个元素,正常寻找前两个值
5. AC代码
class Solution {
public List<List<Integer>> threeSum(int[] num) {
Arrays.sort(num);
// 在需要频繁读取集合中的元素时,使用ArrayList效率较高,而在插入和删除操作较多时,使用LinkedList效率较高。
// 对于此题来说两种都可以。
List<List<Integer>> res = new LinkedList<List<Integer>>();
for (int i = 0; i+2 < num.length; i++) {
// if num[i] already larger than 0, lo and hi will both larger than 0
if(num[i] > 0) break;
// 为了保证不加入重复的 list,因为是有序的,所以如果和前一个元素相同,只需要继续后移就可以
// i==0,正常寻找另两个数;i>0且当前元素不同于前一个元素,正常寻找前两个值
// i>0且当前元素与前一个元素相同,直接进入下一循环,否则本次找到的三个数会与上个循环的三个数完全相同
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
// lo将从前往后遍历,且不与i相同;hi为从后往前遍历
int lo = i+1;
int hi = num.length-1;
int sum = 0 - num[i];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[lo], num[hi]));
// 重复元素跳过
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++;
hi--;
}
else if(num[lo] + num[hi] < sum) lo++;
else hi--;
}
}
}
return res;
}
}
6. 相似题型
【1】 1. Two Sum 题目原址:https://leetcode.com/problems/two-sum/
【2】 15. 3Sum 题目原址: https://leetcode.com/problems/3sum/
【3】 18. 4Sum 题目原址: https://leetcode.com/problems/4sum/
【4】167. Two Sum II - Input array is sorted 题目原址: https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
【5】 560. Subarray Sum Equals K 题目原址:https://leetcode.com/problems/subarray-sum-equals-k/
【6】 653. Two Sum IV - Input is a BST 题目原址:https://leetcode.com/problems/two-sum-iv-input-is-a-bst/
【7】 16. 3Sum Closest 题目原址: https://leetcode.com/problems/3sum-closest/