LeetCode-15.3Sum

Given an array nums of n integers, are there elements abc in nums such that a + bc = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

最简单的办法是暴力,时间复杂度是O(n3)

使用set,时间复杂度为O(n2),

public List<List<Integer>> threeSum(int[] nums) {//set mytip
        Set<List<Integer>> res = new HashSet<>();//使用set可避免重复的组合
        Arrays.sort(nums);//排序结合判断可优化算法
        for (int i = 0; i < nums.length; i++) {
            //if(0==i||(i>=1&&nums[i]!=nums[i-1])){//排序结合判断可优化算法
                Set<Integer> set = new HashSet<>();//存放遍历过的第二个数
                for (int j = i+1; j < nums.length; j++) {
                    int other = 0- nums[i] - nums[j];
                    if(set.contains(other)){
                        List<Integer> list= new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(other);
                        res.add(list);
                    }
                    else{
                        set.add(nums[j]);
                    }

                }
            //}
        }
        return new ArrayList<>(res);
    }

 

使用set,时间复杂度为O(n2),而没有额外空间开销的方法

public List<List<Integer>> threeSum(int[] nums) {//set mytip
        Set<List<Integer>> res = new HashSet<>();
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            int j = i + 1;
            int k = nums.length-1;
            while (j < k) {//j k分别代表第二个数和第三个数,在排好序的数组中 根据当前组合的大小,调节j k的值,更开找到结果,而且不需产生额外空间开销
                if (-nums[i] == (nums[j] + nums[k])) {
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[j]);
                    list.add(nums[k]);
                    res.add(list);
                    j++;
                    k--;
                } else if (-nums[i] > (nums[j] + nums[k])) {
                    j++;
                } else {
                    k--;
                }
            }
        }
        return new ArrayList<>(res);
    }

 

上面的代码可优化成:

public List<List<Integer>> threeSum(int[] num) {
    Arrays.sort(num);
    List<List<Integer>> res = new LinkedList<>(); 
    for (int i = 0; i < num.length-2; i++) {
        if (i == 0 || (i > 0 && num[i] != num[i-1])) {
            int lo = i+1, hi = num.length-1, sum = 0 - num[i];
            while (lo < hi) {
                if (num[lo] + num[hi] == sum) {
                    res.add(Arrays.asList(num[i], num[lo], num[hi]));
                    while (lo < hi && num[lo] == num[lo+1]) lo++;
                    while (lo < hi && num[hi] == num[hi-1]) hi--;
                    lo++; hi--;
                } else if (num[lo] + num[hi] < sum) lo++;
                else hi--;
           }
        }
    }
    return res;
}

 

相关题

两数之和 LeetCode1 https://www.cnblogs.com/zhacai/p/10429120.html

进阶题

四数之和 LeetCode18 https://www.cnblogs.com/zhacai/p/10580394.html

posted @ 2019-03-22 17:12  月半榨菜  阅读(140)  评论(0编辑  收藏  举报