暴力解法(Java)
核心思想: 直接三层for循环+排序+去重,太暴力了,结果很舒适:超时
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);//对数组nums中的元素进行排序
List<List<Integer>> res = new ArrayList<>();//保存三元组结果
Map<List<Integer>,Integer> map = new HashMap<>();//去重专用
if(nums == null || nums.length <= 2)//排除特殊的数组nums
return res;
//直接三层for循环
for(int i = 0; i < nums.length - 2; i++){
for(int j = i + 1; j < nums.length - 1; j++){
for(int k = j + 1; k < nums.length; k++){
if(nums[i] + nums[j] + nums[k] == 0){//满足a+b+c=0条件
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
Collections.sort(list);//对list集合中的元素进行排序
if(!map.containsKey(list)){//利用map去除重复的三元组
map.put(list,i);
res.add(list);
}
}
}
}
}
return res;
}
}
排序+双指针(Java)
核心思想: 对数组nums中的元素进行从小到大排序,第一层for循环实则固定a讨论b和c的变化,第二层for循环随着b增大(左指针右移),c必须同步减小(右指针左移)才有可能满足a+b+c=0条件,若期间遇到相同值,则直接跳过,以达到去重的效果。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);//对数组nums中的元素进行排序
List<List<Integer>> res = new ArrayList<>();//保存三元组结果
for(int a = 0; a < nums.length - 2; a++){
if(a > 0 && nums[a] == nums[a - 1])//a去重
continue;
for(int b = a + 1; b < nums.length - 1; b++){
if(b > a + 1 && nums[b] == nums[b - 1])//b去重(左指针右移)
continue;
int c = nums.length - 1;//获取c的下标
while(c > b && nums[a] + nums[b] + nums[c] > 0)
c--;//c的值同步减小(右指针左移)
if(c == b)//b和c指向相同位置的元素
break;
if(nums[a] + nums[b] + nums[c] == 0){//满足a+b+c=0条件
List<Integer> list = new ArrayList<>();
list.add(nums[a]);
list.add(nums[b]);
list.add(nums[c]);
res.add(list);
}
}
}
return res;
}
}