给定一个数组,给定一个数sum,问这个数组中是否存在两个数a和b,使得a+b=sum。
1.数组排序 O(NlgN)
2.用两个指针first和last分别指向数组的首尾。如果data[first]+data[last]<sum,把first指针往右移动,如果data[first]+data[last]>sum,把last指针往左移动。直到找到data[first]+data[last]=sum,或者两指针相遇。O(N)
最终,O(NlgN)
给定一个数组,给定一个数sum,问这个数组中是否存在三个数a,b和c,使得a+b+c=sum。
1.数组排序 O(NlgN)
2.枚举sum-c,问题转化了和之前一样的问题。O(N*N)
最终,O(N*N)
在leetcode上有道基本一致的题目,只是在那里指定了sum=0。以下是我写的代码,好处是不需要任何额外空间。同时按照题目的要求,增加了去除重复结果的部分。
#include<algorithm>
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<vector<int> > res;
if(num.size()<3) return res;
sort(num.begin(),num.end());
int size = num.size();
for(int indexA=0;indexA<size-2;indexA++){
// remove duplicate
if(indexA!=0&&num[indexA]==num[indexA-1]) continue;
int indexB=indexA+1,indexC=size-1;
while(indexB<indexC){
if(num[indexA]+num[indexB]+num[indexC]==0){
// remove duplicate
if((indexA!=indexB-1)&&(num[indexB]==num[indexB-1])){
indexB++;
indexC--;
continue;
}
vector<int> ans;
ans.push_back(num[indexA]);
ans.push_back(num[indexB]);
ans.push_back(num[indexC]);
res.push_back(ans);
indexB++;
indexC--;
}
else if(num[indexA]+num[indexB]+num[indexC]<0)
indexB++;
else
indexC--;
}
}
return res;
}
};
给定一个数组,问这个数组中是否存在四个数a,b,c和d,使得a+b+c=d。
1.得到一个辅助数组data2,data2=[data[i]+data[j]],另一个辅助数组data3=[data[i]-data[j]]。两个数组的大小都是O(N*N)。
2.问题转化成了data2和data3中是否存在相同的数。先排序O(N*N lg(N*N)),再比较O(N*N)。
最终,O(N*N*lgN)