三数之和
📃 题目描述
🔔 解题思路
回顾下 1. 两数之和 - 力扣(LeetCode) (leetcode-cn.com) (opens new window)和 454. 四数相加 II - 力扣(LeetCode) (leetcode-cn.com) (opens new window),总的思想都是固定一半,然后去找另一半。对于这道题目,找出一个数组中的三个数,我们同样可以固定 a 和 b,去找 c。具体来说,先将这个数组存入 map,然后利用两个 for 循环求出 a 和 b 之和,判断 0-(a+b) 也就是 c 是否在 map 里出现过即可(并且这个 0-(a+b) 还得在 b 的右边))。
具体的细节来说,由于需要避免重复元组,所以我们需要对数组进行一个排序,循环的过程中跳过重复元素。
package com.kami.leetcode.hash_table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* @Description: TODO
* @author: scott
* @date: 2022年02月10日 9:19
*/
public class Solution_15 {
private final static Integer TARGET = 0;
public List<List<Integer>> threeSum(int[] nums){
// 存储三元组
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length < 3){
return res;
}
// 对数组进行排序
Arrays.sort(nums);
// 将数组存入 map, 相等的值只会放进去一个, i为下标
HashMap<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
map.put(nums[i], i);
}
// 两层循环固定 a 和 b
// 遍历获得 a
for(int i = 0; i < nums.length; i++){
// 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
if(nums[i] > 0){
continue;
}
// 对 a 进行去重
if(i > 0 && nums[i] == nums[i - 1]){
continue;
}
// 遍历获得 b
for(int j = i + 1; j < nums.length; j++){
// 对 b 进行去重
if(j > i + 1 && nums[j] == nums[j - 1]){
continue;
}
int c = TARGET - nums[i] - nums[j];
// 尝试从哈希表中获取第三个数字 c, 若存在,并且第三个数字需要在第二个数字右侧(防止重复)
if(map.containsKey(c) && map.get(c) > j){
res.add(Arrays.asList(nums[i], nums[j], c));
}
}
}
return res;
}
}