Leetcode 的Array相关题目,Two Sum,3Sum,3Sum Closet,4Sum。都是给定一个整形数组(以vector形式给出),给定一个target number。在数组里找出若干个数,使得和为target number,或者最接近target number。返回满足条件的数组元素或者元素索引。
错误思路:开始想到的思路,排序后,通过两边指针夹逼的形式,排序复杂度为nlogn,两边夹逼复杂度为n。但是这题要求返回元素位置,而排序改变了元素。自然想到使用map,存储元素位置,但是既然使用了map,这题还得nlogn的复杂度,显然不太科学。于是有了下面的思路。
正确思路:通过一个map存储纪录每个元素的位置。扫一遍数组,对每一个元素,计算gap,然后在map中查找,key为gap的位置是否存在。由于在map中执行find操作,时间复杂度为1,故整体时间复杂度为n, Accepted.
- class Solution {
- public:
- vector<int> twoSum(vector<int> &numbers, int target) {
- vector<int> ret;
- int len = numbers.size();
- map<int, int> mp;
- for (int i = 0; i < len; ++i)
- mp[numbers[i]] = i;
-
- for (int i = 0; i < len; ++i) {
- int gap = target - numbers[i];
- if (mp.find(gap) != mp.end() && mp[gap] != i) {
- ret.push_back(i+1);
- ret.push_back(mp[gap]+1);
- break;
- }
- }
- return ret;
- }
- };
- class Solution {
- public:
- int threeSumClosest(vector<int> &num, int target) {
- int sum = num[0] + num[1] + num[2];
- int gap = abs(sum - target);
- int min_gap = gap;
- int ret = 0;
- sort(num.begin(), num.end());
- for (auto a = num.begin(); a != prev(num.end(), 2); ++a) {
- auto b = next(a);
- auto c = prev(num.end(), 1);
- while (b < c) {
- sum = *a + *b + *c;
- gap = sum - target;
- if (abs(gap) <= min_gap) {
- ret = sum;
- min_gap = abs(gap);
- }
- if (gap == 0)
- return ret;
- else if (gap > 0)
- c--;
- else
- b++;
- }
- }
-
- return ret;
-
- }
- };
- class Solution {
- public:
- vector<vector<int> > threeSum(vector<int> &num) {
- vector<vector<int> > ret;
- if (num.size() < 3)
- return ret;
-
- sort(num.begin(), num.end());
- for (auto a = num.begin(); a != prev(num.end(), 2); ++a) {
- if (a != num.begin() && *a == *(a-1))
- continue;
- auto b = next(a);
- auto c = prev(num.end(), 1);
- while (b < c) {
- int target= *a + *b + *c;
- if (target == 0) {
- ret.push_back({*a, *b, *c});
- ++b;
- while (*b == *(b-1))
- ++b;
- --c;
- while (*c == *(c+1))
- --c;
- }
- else if (target > 0)
- --c;
- else
- ++b;
- }
- }
- return ret;
- }
- };
- class Solution {
- public:
- vector<vector<int> > fourSum(vector<int> &num, int target) {
- vector<vector<int> > ret;
- if (num.size() < 4)
- return ret;
- sort(num.begin(), num.end());
- map<int, vector<pair<int, int> > > mp;
-
- for (int i = 0; i < num.size(); ++i)
- for (int j = i+1; j < num.size(); ++j) {
- int index = num[i] + num[j];
- mp[index].push_back(make_pair(i, j));
- }
-
- int gap = 0;
- for (int i = 0; i < num.size(); ++i) {
- for (int j = i+1; j < num.size(); ++j) {
- gap = target - num[i] - num[j];
- if (mp.find(gap) == mp.end())
- continue;
- auto tmp = mp[gap];
- for (int k = 0; k < tmp.size(); ++k) {
- //if (i <= tmp[k].second)
- // continue;
- //ret.push_back({num[tmp[k].first], num[tmp[k].second], num[i], num[j]});
- if (j >= tmp[k].first)
- continue;
- ret.push_back({num[i], num[j], num[tmp[k].first], num[tmp[k].second]});
-
- }
- }
- }
-
- sort(ret.begin(), ret.end());
- ret.erase(unique(ret.begin(), ret.end()), ret.end());
- return ret;
- }
- };