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.
解题思路一:
四路夹逼,C++:
1 class Solution { 2 public: 3 vector<vector<int> > fourSum(vector<int> &num, int target) { 4 vector<vector<int> > res; 5 if (num.size() <4 ) 6 return res; 7 sort(num.begin(), num.end()); 8 for (int i = 0; i <= num.size() - 4; i++) { 9 for (int j = i + 1; j <= num.size() - 3; j++) { 10 int k = j + 1, l = num.size() - 1; 11 while (k < l) { 12 if (num[i] + num[j] + num[k] + num[l] < target) 13 k++; 14 else if (num[i] + num[j] + num[k] + num[l] > target) 15 l--; 16 else { 17 res.push_back({ num[i], num[j], num[k], num[l] }); 18 k++; 19 l--; 20 while (num[k] == num[k - 1] && k < l) 21 k++; 22 while (num[l] == num[l + 1] && k < l) 23 l--; 24 } 25 } 26 while (j < num.size() - 3 && num[j] == num[j + 1]) 27 j++; 28 } 29 while (i < num.size()-4 && num[i] == num[i + 1]) 30 ++i; 31 } 32 return res; 33 } 34 };
解题思路二:
分治,存储所有2个元素的和,然后采用第一题2sum的思路求解即可,这样时间复杂度不过O(n^2)
JAVA实现如下:
static public List<List<Integer>> fourSum(int[] num, int target) { Set<List<Integer>> set = new LinkedHashSet<List<Integer>>(); HashMap<Integer, List<Integer[]>> hm = new HashMap<Integer, List<Integer[]>>(); Arrays.sort(num); for (int i = 0; i < num.length - 1; i++) for (int j = i + 1; j < num.length; j++) { int sum = num[i] + num[j]; Integer[] tuple = { num[i], i, num[j], j }; if (!hm.containsKey(sum)) hm.put(sum, new ArrayList<Integer[]>()); hm.get(sum).add(tuple); } HashSet<Integer> keys= new HashSet<Integer>(hm.keySet()); for (int key : keys) { if (hm.containsKey(key)) { if (hm.containsKey(target - key)) { List<Integer[]> pairs1 = hm.get(key),pairs2 = hm.get(target - key); for (int i = 0; i < pairs1.size(); ++i) { Integer[] first = pairs1.get(i); for (int j = 0; j < pairs2.size(); ++j) { Integer[] second = pairs2.get(j); if (first[1] != second[1] && first[1] != second[3] && first[3] != second[1] && first[3] != second[3]) { List<Integer> tempList = Arrays.asList(first[0], first[2], second[0], second[2]); Collections.sort(tempList); set.add(tempList); } } } hm.remove(key); hm.remove(target - key); } } } return new ArrayList<List<Integer>>(set); }
C++(TLE):
1 #include<string> 2 #include<vector> 3 #include<set> 4 #include<iterator> 5 #include <stdlib.h> 6 #include<unordered_map> 7 #include<algorithm> 8 using namespace std; 9 class Solution { 10 public: 11 vector<vector<int>> fourSum(vector<int>& nums, int target) { 12 set<vector<int>> res; 13 vector<vector<int>> result; 14 if (nums.size() < 4) 15 return result; 16 sort(nums.begin(), nums.end()); 17 unordered_map<int, vector<vector<int>>> hm ; 18 for (int i = 0; i < nums.size() - 1; i++) { 19 for (int j = i + 1; j < nums.size(); j++) { 20 int sum = nums[i] + nums[j]; 21 vector<int> tuple = { nums[i], i, nums[j], j }; 22 unordered_map<int, vector<vector<int>>>::iterator iter; 23 iter = hm.find(sum); 24 if (iter == hm.end()) { 25 vector<vector<int>> tempv; 26 hm.insert(unordered_map<int, vector<vector<int>>>::value_type(sum, tempv)); 27 } 28 hm[sum].push_back(tuple); 29 } 30 } 31 set<int> keys; 32 unordered_map<int, vector<vector<int>>>::iterator iter; 33 for (iter = hm.begin(); iter != hm.end(); iter++) { 34 keys.insert(iter->first); 35 } 36 for (int key : keys) { 37 unordered_map<int, vector<vector<int>>>::iterator iter; 38 iter = hm.find(key); 39 if (iter != hm.end()){ 40 unordered_map<int, vector<vector<int>>>::iterator iter; 41 iter = hm.find(target - key); 42 if (iter != hm.end()){ 43 vector<vector<int>> pairs1 = hm[key], pairs2 = hm[target - key]; 44 for (int i = 0; i < pairs1.size(); ++i) { 45 vector<int> first = pairs1[i]; 46 for (int j = 0; j < pairs2.size(); ++j) { 47 vector<int> second = pairs2[j]; 48 if (first[1] != second[1] && first[1] != second[3] 49 && first[3] != second[1] 50 && first[3] != second[3]) { 51 vector<int> tempList = { first[0],first[2], second[0], second[2] }; 52 sort(tempList.begin(), tempList.end()); 53 res.insert(tempList); 54 } 55 } 56 } 57 hm.erase(key); 58 hm.erase(target - key); 59 } 60 } 61 } 62 copy(res.begin(), res.end(), back_inserter(result)); 63 return result; 64 } 65 };