3Sum
Given anarray S of n integers,are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in thearray which gives the sum of zero.
找到一个数组中3个数字。使得3个数字相加等于0。
方法1:O(n^3)
利用暴力搜索。既然是三个数字,那么在n个数字中选择3个,一共有n(n-1)(n-2)/6种情况(n>2)。复杂度为O(n^3)。
方法2:O(n*m*longn。)
3个数字相加,一共有3种情况是为0:三个数字都为0;有一个数字为0,另外两个是相反数;三个数字都不为0,;
1. 先遍历一遍数组,然后把数组分成两个数组,一个数组中所有元素都小于0,另外一个全都大于等于0,然后排序这个两个数组。
2. 考虑到第一种情况和第二种情况,都至少有一个负数,从负数数组开始遍历,选择一个负数,再从另外一个大于等于0数组从头开始遍历,求得它们的和后判断和是大于等于0还是小于0,然后再利用二分法查找数组。
3. 最后再看看一共有几个0,若超过3个,就追加3个0进数组。
ps:有个小细节,需要注意就是重复的数字。
复杂度分析:
假设数组长为N。分成两个数组为,n,m。
第一步需要遍历数组,分成两个部分,然后排序。需要NlongN(近似)。第二步要遍历这两个数组,并查找,为n*m*longn。
方法3:O(n^2)
利用之前写到的2SUM来进行加工,因为2SUM的复杂度为O(n),这里只需要将原来的数组排序好后,遍历一次数组,其中数组的每一个元素都是target的值,然后稍微修改一下2SUM就可以。http://blog.csdn.net/laeen/article/details/54570971
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target , int start) {
map<int,int> mymap;
pair <int,int> p;
map<int,int>::iterator it;
map<int,int>::iterator it1;
vector<int> v;
int flag = 0;
int s = nums.size();
for(int i = start ; i < s ; i++){
p.first = nums[i];
p.second = i;
if(mymap.count(p.first) && flag == 0)
if(target == 2 * p.first){
it = mymap.find(p.first);
v.push_back(-target);
v.push_back((*it).first);
v.push_back(p.first);
flag = 1; //设置标记,若有重复的数字,比如nums为0 0 0 0这样的就会出现三种结果,利用flag可以避免重复
}
mymap.insert(p);
}
for(it = mymap.begin(); it != mymap.end(); it++){
int r = target - (*it).first;
it1 = mymap.find(r) ;
if(it1 != mymap.end() && it1 != it && (*it).first < (*it1).first){
v.push_back(-target);
v.push_back((*it).first);
v.push_back((*it1).first);
}
}
return v;
}
vector< vector<int> > threeSum(vector<int>& nums) {
vector< vector<int> > r;
vector<int> v;
vector<int> n;
int count = 0;
int before = 1;
sort(nums.begin(),nums.end());
for(int i = 0 ; i < nums.size() ; i++){
if(before == nums[i]){
continue; //避免重复的数字
}
before = nums[i];
v.clear();
v = twoSum(nums,0-nums[i] ,i + 1);
for(int i = 0 ; i < v.size() ; i+=3){
n.clear();
for(int k = i ; k < i + 3 ; k++){
n.push_back(v[k]);
}
r.push_back(n);
}
}
return r;
}
};