LeetCode 热题 100打卡第五天
三数之和(LeeCode第15题)
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。**注意:**答案中不可以包含重复的三元组。
解法一:套用两层for循环同时利用hashmap中的containsKey函数找到第三个值,最后利用HashSet里面的值不能重复,来满足答案中不可以包含重复的三元组这样的条件。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
HashMap<Integer, Integer> heap = new HashMap<>();
for(int i = 0; i < nums.length; i++){
heap.put(nums[i], i);
}
Set<List<Integer>> res = new HashSet<>();
for(int j = 0; j < nums.length; j++){
for(int k = j + 1; k < nums.length; k++){
int n = nums[j] + nums [k];
if(heap.containsKey(-n)){
int t = heap.get(-n);
if((t != j) &&(t != k)){
List<Integer> ans = Arrays.asList(nums[j] , nums[k] , nums[t]);
Collections.sort(ans);
res.add(ans);
}
}
}
}
return new ArrayList<>(res);
}
}
解法二:首先令这三个元素的在数组元素中的下标分别为i,j,k,先确定好i的值,接着对j,k用双指针遍历,与上一种方式相比,这种方式所占用的空间复杂度要更小一点。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
for(int i = 0; i < n; i++){
if(i !=0 && nums[i] ==nums[i - 1]) continue;
for(int j = i + 1, k = nums.length - 1; j < k; ++j){
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
while((j < k - 1) && (nums[i] + nums[j] + nums[k - 1] >= 0)){
k--;
}
if(nums[i] + nums[j] + nums[k] == 0){
ans.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[k])));
}
}
}
return ans;
}
}