1. Two Sum
由于要返回index+1, 用unordered_map存elem到index的映射,注意这样的testcase:[2,3,5], 4
<span style="font-size:14px;">class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
unordered_map<int, int> num2index;
for (int i=0; i<numbers.size(); ++i) num2index[numbers[i]] = i;
vector<int> rs;
for (int i=0; i<numbers.size(); ++i) {
int left = target - numbers[i];
if (num2index.find(left) != num2index.end() && num2index[left] != i) {
rs.push_back(i+1); rs.push_back(num2index[left]+1);
break;
}
}
return rs;
}
};</span>
要求返回最近的那个和。这个就可以先排序了,因为扫描的时间复杂度起码O(n^2)。
<span style="font-size:14px;">class Solution {
public:
int threeSumClosest(vector<int> &num, int target) {
int mini = INT_MAX;
int rs = 0;
sort(num.begin(), num.end());
int n = num.size();
for(int i=0; i<n-2; ++i) {
for (int j=i+1, k=n-1; j<k;) { //夹逼
int now = num[i] + num[j] + num[k];
int gap = abs(now-target);
rs = gap < mini ? now : rs; //注意这句和下句的顺序
mini = gap < mini ? gap : mini;
if (now > target) --k;
else ++j;
}
}
return rs;
}
};</span>
要求返回所有和为0的结果。和上一题相比主要困难的地方在于去重, 都必须计算第一个出现的元素,后面重复的就continue过,而不能遇到最后一个不重的才计算。注意下面这种代码的写法和直接对num去重的区别!(去重去的是num[a]和num[a-1]的那些num[a],.., 而不是去掉这种num[a] = num[b] = num[c])此外注意当sum == 0的时候,++b和--c要同时进行。
注意,这里的夹逼法和Container With Most Water的联系!!
<span style="font-size:14px;">class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > rs;
sort(num.begin(), num.end());
int n = num.size();
for (int a=0; a<n-2; ++a) {
if (a>0 && num[a-1] == num[a]) continue;
for (int b=a+1, c=n-1; b<c;)
{
if (b > a+1 && num[b-1] == num[b]) { //去重
++b; continue;
}
if (c < n-1 && num[c+1] == num[c]) { //去重
--c; continue;
}
int sum = num[a] + num[b] + num[c];
if (sum == 0){
vector<int> tmp({num[a], num[b], num[c]});
rs.push_back(tmp);
++b; --c;
}
else if (sum < 0)
++b;
else
--c;
}
}
return rs;
}
};</span>
和上面的3sum一模一样。
<span style="font-size:14px;">class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int>> rs;
sort(num.begin(), num.end());
int n = num.size();
for(int a=0; a < n-3; a++) {
if (a>0 && num[a] == num[a-1]) continue;
for (int b=a+1; b < n - 2; ++b) {
if (b > a+1 && num[b] == num[b-1]) continue;
for (int c = b+1, d = n-1; c < d;) {
if (c > b+1 && num[c] == num[c-1]) {
++c; continue;
}
if (d < n - 1 && num[d] == num[d+1]) {
--d; continue;
}
int sum = num[a] + num[b] + num[c] + num[d];
if (sum == target)
{
vector<int> tmp({num[a], num[b], num[c], num[d]});
rs.push_back(tmp);
++c; --d;
}
else if(sum < target) ++c;
else --d;
}
}
}
return rs;
}
};</span>
大家有更简洁精炼的代码,一起讨论啊!