zoukankan      html  css  js  c++  java
  • Leetcode: 4Sum

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
    
    Note:
    Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    The solution set must not contain duplicate quadruplets.
        For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
    
        A solution set is:
        (-1,  0, 0, 1)
        (-2, -1, 1, 2)
        (-2,  0, 0, 2)

    可以按照3Sum的思路来做,并以此类推,KSum的复杂度就是O(N^(k-1)). 在3Sum外面再套一层循环,相当于N次求3Sum

    若还有时间,可以参考https://discuss.leetcode.com/topic/29585/7ms-java-code-win-over-100

    有更多优化

    Time: O(N^3)

    It can be proved that the lower bound of time complexity is O(N^3)

     1 public class Solution {
     2     public List<List<Integer>> fourSum(int[] num, int target) {
     3         List<List<Integer>> res = new ArrayList<List<Integer>>();
     4         if (num==null || num.length==0) return res;
     5         Arrays.sort(num);
     6         
     7         int max = num[num.length-1];
     8         if (4 * num[0] > target || 4 * max < target)
     9             return res;
    10         
    11         for (int i=num.length-1; i>=3; i--) {
    12             if (i<num.length-1 && num[i]==num[i+1]) continue;
    13             threeSum(0, i-1, num, target-num[i], res, num[i]);
    14         }
    15         return res;
    16     }
    17     
    18     public void threeSum(int start, int end, int[] num, int target, List<List<Integer>> res, int last1) {
    19         for (int i=end; i>=2; i--) {
    20             if (i<end && num[i]==num[i+1]) continue;
    21             twoSum(0, i-1, num, target-num[i], res, num[i], last1);
    22         }
    23     }
    24     
    25     public void twoSum(int l, int r, int[] num, int target, List<List<Integer>> res, int last2, int last1) {
    26         while (l < r) {
    27             if (num[l]+num[r] == target) {
    28                 List<Integer> set = new ArrayList<Integer>();
    29                 set.add(num[l]);
    30                 set.add(num[r]);
    31                 set.add(last2);
    32                 set.add(last1);
    33                 res.add(new ArrayList<Integer>(set));
    34                 l++;
    35                 r--;
    36                 while (l<r && num[l] == num[l-1]) {
    37                     l++;
    38                 }
    39                 while (l<r && num[r] == num[r+1]) {
    40                     r--;
    41                 }
    42             }
    43             else if (num[l]+num[r] < target) {
    44                 l++;
    45             }
    46             else {
    47                 r--;
    48             }
    49         }
    50     }
    51 }
  • 相关阅读:
    hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
    bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
    codevs 1191 树轴染色 线段树区间定值,求和
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
    tyvj:1038 忠诚 线段树 区间查询
    KL散度
    NumPy 从已有的数组创建数组
    NumPy 创建数组
    NumPy 数组属性
    NumPy 数据类型
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/4020087.html
Copyright © 2011-2022 走看看