zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    codeforces 1060 B
    codeforces 1060 A
    牛客 国庆七天乐 day1 L
    BZOJ 1087: [SCOI2005]互不侵犯King
    codeforces 792CDivide by Three(两种方法:模拟、动态规划
    codeforces 797C Minimal string
    codeforces 110E Lucky Tree
    codeforces 798D
    2017福建省赛 FZU2272~2283
    Android -- Looper、Handler、MessageQueue等类之间关系的序列图
  • 原文地址:https://www.cnblogs.com/zhacai/p/10579514.html
Copyright © 2011-2022 走看看