LeetCode OJ 之 4Sum (”四個數的和“)
阿新 • • 發佈:2019-02-19
題目:
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)
思路:
程式碼:
class Solution { public: vector<vector<int>> fourSum(vector<int>& num, int target) { vector<vector<int> > result; if (num.size() < 4) return result; sort(num.begin(), num.end()); vector<int>::iterator last = num.end(); for (vector<int>::iterator a = num.begin(); a < last - 3 ; ++a) { for (vector<int>::iterator b = a + 1 ; b < last - 2 ; ++b) { vector<int>::iterator c = b + 1 ; vector<int>::iterator d = last - 1 ; while (c < d) { if (*a + *b + *c + *d < target) { ++c; } else if (*a + *b + *c + *d > target) { --d; } else { result.push_back({ *a, *b, *c, *d }); ++c; --d; } } } } sort(result.begin(), result.end());//注意sort不是vector的庫函式,而是algorithm庫的泛型演算法sort //unique的功能是去除相鄰的重複元素(只保留一個),其實它並不真正把重複的元素刪除,而是把重複的元素移到後面去了 //然後返回的迭代器指向超出無重複的元素範圍末端的下一個位置。因為unique去除的是相鄰的重複元素,所以一般用之前都會要排一下序。 //然後呼叫erase刪除後面的重複的元素 result.erase(unique(result.begin(), result.end()), result.end()); return result; } };
程式碼2:
//map 做快取 // LeetCode, 4Sum // 用一個 hashmap 先快取兩個數的和 // 時間複雜度,平均 O(n^2) ,最壞 O(n^4) ,空間複雜度 O(n^2) class Solution { public: vector<vector<int> > fourSum(vector<int> &num, int target) { vector<vector<int> > result; if (num.size() < 4) return result; sort(num.begin(), num.end()); unordered_map<int, vector<pair<int, int> > > cache; //把num中任意兩個數的和作為鍵,這兩個數的下標對作為值儲存在cache中,(小的在前,大的在後)如果有兩對數的和相同,則鍵相同,下標對放在同一個vector裡 for (size_t a = 0; a < num.size(); ++a) { for (size_t b = a + 1; b < num.size(); ++b) { cache[num[a] + num[b]].push_back(pair<int, int>(a, b)); } } for (int c = 0; c < num.size(); ++c) { for (size_t d = c + 1; d < num.size(); ++d) { int key = target - num[c] - num[d]; //如果key能在cache中的鍵中找到,則找到符合條件的,否則繼續查詢 if (cache.find(key) == cache.end()) continue; vector<pair<int, int> > vec = cache[key];//vec裡面可能有多個pair for (size_t k = 0; k < vec.size(); ++k) { if (c <= vec[k].second) continue; // 為了防止重疊,可以讓 c > vec[k].second 或者 d < vec[k].first result.push_back( { num[vec[k].first],num[vec[k].second], num[c], num[d] }); // if (d >= vec[k].first) // continue; // result.push_back( { num[c], num[d] , num[vec[k].first],num[vec[k].second] }); } } } sort(result.begin(), result.end()); result.erase(unique(result.begin(), result.end()), result.end()); return result; } };