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

  • 相关阅读:
    左孩子右兄弟的字典树
    UVA 1401 Remember the Word
    HDOJ 4770 Lights Against Dudely
    UvaLA 3938 "Ray, Pass me the dishes!"
    UVA
    Codeforces 215A A.Sereja and Coat Rack
    Codeforces 215B B.Sereja and Suffixes
    HDU 4788 Hard Disk Drive
    HDU 2095 find your present (2)
    图的连通性问题—学习笔记
  • 原文地址:https://www.cnblogs.com/zhacai/p/10579514.html
Copyright © 2011-2022 走看看