原題鏈接: http://oj.leetcode.com/problems/4sum/
這道題要求跟3Sum差不多,只是需求擴展到四個的數字的和了。我們還是可以按照3Sum中的解法,只是在外面套一層循環,相當於求n次3Sum。我們知道3Sum的時間復雜度是O(n^2),所以如果這樣解的總時間復雜度是O(n^3)。代碼如下:
public ArrayList> fourSum(int[] num, int target) { ArrayList> res = new ArrayList>(); if(num==null||num.length==0) return res; Arrays.sort(num); for(int i=num.length-1;i>2;i--) { if(i==num.length-1 || num[i]!=num[i+1]) { ArrayList> curRes = threeSum(num,i-1,target-num[i]); for(int j=0;j上述這種方法比較直接,根據3Sum的結果很容易進行推廣。那麼時間復雜度能不能更好呢?其實我們可以考慮用二分法的思路,如果把所有的兩兩pair都求出來,然後再進行一次Two Sum的匹配,我們知道Two Sum是一個排序加上一個線性的操作,並且把所有pair的數量是O((n-1)+(n-2)+...+1)=O(n(n-1)/2)=O(n^2)。所以對O(n^2)的排序如果不用特殊線性排序算法是O(n^2*log(n^2))=O(n^2*2logn)=O(n^2*logn),算法復雜度比上一個方法的O(n^3)是有提高的。threeSum(int[] num, int end, int target) { ArrayList> res = new ArrayList>(); for(int i=end;i>1;i--) { if(i==end || num[i]!=num[i+1]) { ArrayList> curRes = twoSum(num,i-1,target-num[i]); for(int j=0;j twoSum(int[] num, int end, int target) { ArrayList> res = new ArrayList>(); int l=0; int r=end; while(l item = new ArrayList (); item.add(num[l]); item.add(num[r]); res.add(item); l++; r--; while(l target) { r--; } else { l++; } } return res; }
private ArrayList> twoSum(ArrayList第二種方法比第一種方法時間上還是有提高的,其實這道題可以推廣到k-Sum的問題,基本思想就是和第二種方法一樣進行二分,然後兩兩結合,不過細節就非常復雜了(這點從上面的第二種解法就能看出來),所以不是很適合在面試中出現,有興趣的朋友可以進一步思考或者搜索網上材料哈。pairs, int target){ HashSet hashSet = new HashSet (); int l = 0; int r = pairs.size()-1; ArrayList> res = new ArrayList>(); while(l =rEnd;j--) { if(check(pairs.get(i),pairs.get(j))) { ArrayList item = new ArrayList (); item.add(pairs.get(i).nodes[0].value); item.add(pairs.get(i).nodes[1].value); item.add(pairs.get(j).nodes[0].value); item.add(pairs.get(j).nodes[1].value); //Collections.sort(item); Tuple tuple = new Tuple(item); if(!hashSet.contains(tuple)) { hashSet.add(tuple); res.add(tuple.num); } } } } l = lEnd+1; r = rEnd-1; } else if(pairs.get(l).getSum()+pairs.get(r).getSum()>target) { r--; } else{ l++; } } return res; } private boolean check(Pair p1, Pair p2) { if(p1.nodes[0].index == p2.nodes[0].index || p1.nodes[0].index == p2.nodes[1].index) return false; if(p1.nodes[1].index == p2.nodes[0].index || p1.nodes[1].index == p2.nodes[1].index) return false; return true; }