LeetCode 18.4Sum

题目:

Given an array S of n integers, are there elements abc, 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的时候我就在想如果出现更多个数该怎么办。网上一搜,在国外网站上看到了理论上的一种通用解法

k -SUM can be solved more quickly as follows.

  • For even  k : Compute a sorted list  S  of all sums of  k/2  input elements. Check whether  S  contains both some number  x  and its negation  x . The algorithm runs in  O(nk/2logn)  time.

  • For odd  k : Compute the sorted list  S  of all sums of  (k1)/2  input elements. For each input element  a , check whether  S  contains both  x  and  ax , for some number  x . (The second step is essentially the  O(n2) -time algorithm for 3SUM.) The algorithm runs in  O(n(k+1)/2)  time.

Both algorithms are optimal (except possibly for the log factor when  k  is even and bigger than  2 ) for any constant  k  in a certain weak but natural restriction of the linear decision tree model of computation. For more details, see:

  • Nir Ailon and Bernard Chazelle. Lower bounds for linear degeneracy testing. JACM 2005.

  • Jeff Erickson. Lower bounds for linear satisfiability problems. CJTCS 1999.

好吧,这种解法没有我想象中那么惊艳。。。维护一个有序的S,它保存了任意K/2个数的和。设一头一尾两指针,对于每一个S[i],看看是否存在S[j]使得他们的和是target,所以空间复杂度为O(n^(k/2)),时间复杂度为O(n^(k/2)logn)。其实在维护了S之后,就相当于是2sum这个问题了。
如果利用hashtable的方法是不需要排序的,把每两个数的和加入hashtable。然后遍历,从中挑出一个数x,看看(target - x)是不是在hashtable中。这样复杂度为O(n^2)。
这些方法最大的问题在于如何消除重复解。想来想去,解的存放还是要使用hashtable。
S不需要有序且有key-value的对应关系,且同一个key和可以有多个不同的value,所以可以用multimap来实现,解集没有key-value的对应关系,且不允许重复,所以可以用unordered_set。涉及到具体实现的时候,unordered_set把我难住了,想用它还要自己定义hash函数。不得不说这一点上java比cpp更方便啊。。。
最后用了和3SUM一模一样的方法,只不过多了个循环,代码就不贴了。

你可能感兴趣的:(array,Two,Pointers)