15.三数之和
1、暴力枚举+链表元素去重
不出意外直接超时

class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int size = nums.length;
            //枚举所有结果
            Arrays.sort(nums);
            List<List<Integer>> res = new LinkedList<>();
            for(int i = 0; i < size; i++){
                for(int j = i + 1; j < size; j++){
                    for(int k = j + 1; k < size; k++){
                        if(nums[i] + nums[j] + nums[k] == 0){
                            ArrayList<Integer> l = new ArrayList(Arrays.asList(nums[i],nums[j], nums[k]));
                            res.add(l);
                        }
                    }
                }
            }
            //排序去重
            Collections.sort(res, (o1, o2) -> {
                if(o1.get(0).equals(o2.get(0))){
                    if(o1.get(1).equals(o2.get(1))){
                        if(o1.get(2).equals(o2.get(2))){
                            return 0;
                        }
                        return o1.get(2)-o2.get(2);
                    }
                    return o1.get(1)-o2.get(1);
                }
                return o1.get(0) - o2.get(0);
            });
            List<Integer> pre = null;
            for(int i = 0; i < res.size();){
                if( pre != null && pre.get(0).equals(res.get(i).get(0)) && pre.get(1).equals(res.get(i).get(1)) && pre.get(2).equals(res.get(i).get(2))){
                    res.remove(i);
                }else{
                    pre = res.get(i);
                    i++;
                }
            }
            return res;
        }
    }
可恶还是无法AC么。。

2.在暴力枚举的基础上考虑两个数的和利用HashMap优化复杂度

class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int size = nums.length;
            Arrays.sort(nums);
            HashMap<Integer, Integer> map = new HashMap<>();
            for(int i = 0; i < size; i++){
                map.put(nums[i],i);
            }
            //枚举所有结果
            List<List<Integer>> res = new LinkedList<>();
            for(int i = 0; i < size; i++){
                for(int j = i + 1; j < size; j++){
                        Integer k = map.get(0 - nums[i] - nums[j]);
                        if(k!=null&& k > j){
                            ArrayList<Integer> l = new ArrayList(Arrays.asList(nums[i],nums[j], nums[k]));
                            res.add(l);
                        }
                }
            }
            //排序去重
            Collections.sort(res, (o1, o2) -> {
                if(o1.get(0).equals(o2.get(0))){
                    if(o1.get(1).equals(o2.get(1))){
                        if(o1.get(2).equals(o2.get(2))){
                            return 0;
                        }
                        return o1.get(2)-o2.get(2);
                    }
                    return o1.get(1)-o2.get(1);
                }
                return o1.get(0) - o2.get(0);
            });
            List<Integer> pre = null;
            for(int i = 0; i < res.size();){
                if( pre != null && pre.get(0).equals(res.get(i).get(0)) && pre.get(1).equals(res.get(i).get(1)) && pre.get(2).equals(res.get(i).get(2))){
                    res.remove(i);
                }else{
                    pre = res.get(i);
                    i++;
                }
            }
            return res;
        }
    }
优化之后就多跑了一个样例,哈基和你这家伙。。

3. 在两个数之和中不能对数组排序是因为要求返回数组下标,一经排序下标就乱了,但是本题目不需要返回下标,所以可以排序利用双指针降低复杂度
class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int size = nums.length;
            Arrays.sort(nums);
            List<List<Integer>> res = new LinkedList<>();
            int a = 1, b = 1, c = 1;
            int h, t;
            for (int i = 0; i < size; i++) {
                h = i + 1;
                t = size - 1;
                //寻找和为0-nums[i]的两个数
                while (h < t) {
                    if (nums[h] + nums[t] < 0 - nums[i]) {
                        h++;
                    } else if (nums[h] + nums[t] > 0 - nums[i]) {
                        t--;
                    } else {
                        List<Integer> list = new ArrayList<>(Arrays.asList(nums[i], nums[h], nums[t]));
                        res.add(list);
                        int old_h = nums[h];
                        while(h < t && old_h == nums[++h]);
                        int old_t = nums[t];
                        while(h < t && old_t == nums[--t]);
                    }
                }
            }
             //排序去重
            Collections.sort(res, (o1, o2) -> {
                if(o1.get(0).equals(o2.get(0))){
                    if(o1.get(1).equals(o2.get(1))){
                        if(o1.get(2).equals(o2.get(2))){
                            return 0;
                        }
                        return o1.get(2)-o2.get(2);
                    }
                    return o1.get(1)-o2.get(1);
                }
                return o1.get(0) - o2.get(0);
            });
            List<Integer> pre = null;
            for(int i = 0; i < res.size();){
                if( pre != null &&
                  pre.get(0).equals(res.get(i).get(0)) &&
                  pre.get(1).equals(res.get(i).get(1)) &&
                  pre.get(2).equals(res.get(i).get(2))){
                    res.remove(i);
                }else{
                    pre = res.get(i);
                    i++;
                }
            }
            return res;
        }
    }
终于。。超过百分之五也是神人了

一直以为HashSet去重比较的是地址就没敢用,我太蠢了
用HashSet复杂度比自己的去重低一点
class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int size = nums.length;
            Arrays.sort(nums);
            HashSet<List<Integer>> set = new HashSet<>();
            int a = 1, b = 1, c = 1;
            int h, t;
            for (int i = 0; i < size; i++) {
                h = i + 1;
                t = size - 1;
                //寻找和为0-nums[i]的两个数
                while (h < t) {
                    if (nums[h] + nums[t] < 0 - nums[i]) {
                        h++;
                    } else if (nums[h] + nums[t] > 0 - nums[i]) {
                        t--;
                    } else {
                        List<Integer> list = new ArrayList<>(Arrays.asList(nums[i], nums[h], nums[t]));
                        Collections.sort(list);
                        set.add(list);
                        int old_h = nums[h];
                        while(h < t && old_h == nums[++h]);
                        int old_t = nums[t];
                        while(h < t && old_t == nums[--t]);
                    }
                }
            }
            List<List<Integer>> res = new LinkedList<>(set);
            return res;
        }
    }

                    
                
                
            
        
浙公网安备 33010602011771号