中级农民
- 积分
- 126
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2015-4-22
- 最后登录
- 1970-1-1
|
本帖最后由 zhuli19901106 于 2015-7-19 23:13 编辑
4 Sum
题意:给定一个未排序数组,求其中加起来等于target的组合a + b + c + d。
解法1:两个维度用遍历解决,另两个维度使用two sum的解法。查重依然是偷懒的签名+哈希。话说我要是用位运算配合加减法来算签名,应该速度会快得多吧。
代码1:- #include <algorithm>
- #include <string>
- #include <unordered_set>
- using namespace std;
- class Solution {
- public:
- /**
- * @param numbers: Give an array numbersbers of n integer
- * @param target: you need to find four elements that's sum of target
- * @return: Find all unique quadruplets in the array which gives the sum of
- * zero.
- */
- vector<vector<int> > fourSum(vector<int> nums, int target) {
- ans.clear();
- vector<int> &a = nums;
- vector<int> v(4);
- int n = nums.size();
- int i1, i2, i3, i4;
-
- sort(a.begin(), a.end());
- for (i1 = 0; i1 < n - 3; ++i1) {
- for (i4 = i1 + 3; i4 < n; ++i4) {
- i2 = i1 + 1;
- i3 = i4 - 1;
- while (i2 < i3) {
- if (a[i1] + a[i2] + a[i3] + a[i4] < target) {
- ++i2;
- } else if (a[i1] + a[i2] + a[i3] + a[i4] > target) {
- --i3;
- } else {
- v[0] = a[i1];
- v[1] = a[i2];
- v[2] = a[i3];
- v[3] = a[i4];
- string s = calcSign(v);
- if (us.find(s) == us.end()) {
- ans.push_back(v);
- us.insert(s);
- }
- ++i2;
- }
- }
- }
- }
- us.clear();
- return ans;
- }
- private:
- unordered_set<string> us;
- vector<vector<int> > ans;
-
- string calcSign(vector<int> &v) {
- int n = v.size();
- string s = "";
- int i;
- for (i = 0; i < n; ++i) {
- s += to_string(v[i]);
- }
- return s;
- }
- };
复制代码 复杂度1:时间O(N ^ 3),空间O(N ^ 4)。
解法2:依然是用跳过相等元素的方法来去重。
代码2:- // Without hashing
- #include <algorithm>
- using namespace std;
- class Solution {
- public:
- /**
- * @param numbers: Give an array numbersbers of n integer
- * @param target: you need to find four elements that's sum of target
- * @return: Find all unique quadruplets in the array which gives the sum of
- * zero.
- */
- vector<vector<int> > fourSum(vector<int> nums, int target) {
- ans.clear();
- vector<int> &a = nums;
- vector<int> v(4);
- int n = nums.size();
- int i1, i2, i3, i4;
-
- sort(a.begin(), a.end());
- i1 = 0;
- while(i1 < n) {
- i4 = n - 1;
- while (i4 > i1) {
- i2 = i1 + 1;
- i3 = i4 - 1;
- while (i2 < i3) {
- if (a[i1] + a[i2] + a[i3] + a[i4] < target) {
- ++i2;
- } else if (a[i1] + a[i2] + a[i3] + a[i4] > target) {
- --i3;
- } else {
- v[0] = a[i1];
- v[1] = a[i2];
- v[2] = a[i3];
- v[3] = a[i4];
- ans.push_back(v);
- i2 = nextPos(a, n, i2);
- }
- }
- i4 = lastPos(a, i1, i4);
- }
- i1 = nextPos(a, n, i1);
- }
- return ans;
- }
- private:
- vector<vector<int> > ans;
-
- int lastPos(vector<int> &a, int n, int i) {
- int val = a[i];
- while (i > n && a[i] == val) {
- --i;
- }
- return i;
- }
-
- int nextPos(vector<int> &a, int n, int i) {
- int val = a[i];
- while (i < n && a[i] == val) {
- ++i;
- }
- return i;
- }
- };
复制代码 复杂度2:时间O(N ^ 3),空间O(1)。
|
|