问题描述
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
暴力法
套三层循环,如果为零就添加,这个方法可以解决,但是用时会超过限制
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
Map<String, Integer> map = new HashMap();
List<List<Integer>> result = new ArrayList<List<Integer>>();
for(int i = 0; i+2 < 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){
String str = new String();
str += nums[i];
str += nums[j];
str += nums[k];
if(map.get(str)!=null){
continue;
}else{map.put(str,1);}
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
result.add(list);
}
}
}
}
return result;
}
}
通用解法
leetcode上通过的算法都大同小异,基本思想都是一样的。第一层遍历所有数,里面定义前后两个变量j=i+1和k=nums.length,两头向中间遍历。在遍历前先用系统函数将数组排序,然后遍历过程中如果当前的数字和上一个相同直接跳过,时间复杂度为O(n^2)。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i + 2 < nums.length; i++) {
if (i > 0 && nums[i] == nums[i - 1]) { // skip same result
continue;
}
int j = i + 1, k = nums.length - 1;
int target = -nums[i];
while (j < k) {
if (nums[j] + nums[k] == target) {
res.add(Arrays.asList(nums[i], nums[j], nums[k]));
j++;
k--;
while (j < k && nums[j] == nums[j - 1]) j++; // skip same result
while (j < k && nums[k] == nums[k + 1]) k--; // skip same result
} else if (nums[j] + nums[k] > target) {
k--;
} else {
j++;
}
}
}
return res;
}
}