LeetCode15.三数之和

发布时间 2023-10-25 00:07:46作者: 白布鸽

题目描述

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例

image

第一次提交的代码

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Map<Integer,Integer> map=new HashMap<>();
        Set<Set<Integer>> set = new HashSet<>();
        List<List<Integer>> result=new ArrayList<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],i);
        }

        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
                int minus=0-(nums[i]+nums[j]);
                if(map.get(minus)!=null&&(map.get(minus)!=i&&map.get(minus)!=j)){
                    Set<Integer> tempSet=new HashSet<>(Arrays.asList(nums[i],nums[j],minus));
                    if(!set.contains(tempSet)){
                        result.add(Arrays.asList(nums[i],nums[j],minus));
                        set.add(tempSet);
                    }          
                }
            }
        }
        return result;
    }
}

时间复杂度也是O(n^2),但是提交的时候显示超出时间限制,个人纳闷看了一下大神的解法,也是这个时复,感觉上像是我这里用了Set来去重耗费时间太久了还是怎么样?实在没弄清楚。

学习到的东西

大神的方法用的是双指针法(根本想不到用这个,还在想用哈希法来解决问题呢...)
因为我语言表达太难,大佬有图可以帮助理解,具体的链接我放在这(偷个懒):
三数相加--Carl大佬

最终的代码

mport java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        int left=0;
        int right=0;
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0)return result;
            //对A去重
            if(i>0&&nums[i-1]==nums[i])continue;

            left=i+1;
            right=nums.length-1;
            while(left<right){
                if((nums[i]+nums[left]+nums[right])>0)right--;
                else if((nums[i]+nums[left]+nums[right])<0)left++;
                else{
                    //三数之和正好等于0
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    //对B和C去重
                    while(left<right&&nums[left+1]==nums[left])left++;
                    while(left<right&&nums[right-1]==nums[right])right--;
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
}