1. 2Sum:等于某值result的结合(a,b)
- 首先将数值进行排序,然后使用两个指针p1,p2,p1指向头,p2指向尾,然后求和比较,如果大于result,则p2--,如果小于result,则p1++,否则p1和p2所指的值即为所求;时间复杂调度:O(nlogn)
2.3Sum (数组里面的元素可以不连续)
- 第一个问题:将其进行转换成2Sum。取第一个值count,则后面的值其和加起来为:-count;
- 第二个问题:去除重复的组。如果后面那个值和前面一个值相等,则终止该次循环,进入下一次,2Sum的处理同上;
vector<vector<int> > threeSum(vector<int> &num)
{
sort(num.begin(), num.end() );
vector<int> temp;
vector<vector<int> > result;
vector<int>::iterator iter=num.begin();
if(num.size()<3) //error1:输入就明显不合要求 []
return result;
for(; iter!=num.end()-2; iter++)
{
if(iter!=num.begin() && *(iter-1) == *iter) //去重:因为相同的数字,得到的组合是一样的
continue;
vector<int>::iterator iter1=iter+1, iter2=num.end()-1;
int count = (-1)*(*iter);
while(iter1 < iter2)
{
if(iter1!=iter+1 && *(iter1-1) == *iter1)<span style="font-family: Arial, Helvetica, sans-serif;">//去重:因为相同的数字,得到的组合是一样的</span>
{
iter1++; //error2:要想后走一位 [-1,-1,-1,1]
continue;
}
if((*iter1+*iter2) == count)
{
temp.push_back(*iter);
temp.push_back(*iter1);
temp.push_back(*iter2);
result.push_back(temp);
temp.clear();
iter1++;
iter2--;
}
else if((*iter1+*iter2) > count)
iter2--;
else
iter1++;
}
}
}
3.3Sum closest to target
- 思路同2,但是需要将三个数之和与target进行比较,如果大,需要将和变小,右指针向前移动;如果小,需要将和变大,左指针向后移动;如果等于,则直接返回;中途用一个值来保存
//题目可以假设只有一种结果
int threeSumClosest(vector<int> &num, int target)
{
if(num.size()<3)
return accumulate(num.begin(), num.end(),0);
sort(num.begin(), num.end());
vector<int>::iterator iter = num.begin();
int result = *iter + *(iter+1) + *(iter+2); //初始化
for( ; iter!=num.end()-2; iter++)
{
vector<int>::iterator iter1=iter+1, iter2 = num.end()-1;
while(iter1<iter2)
{
int sum = *iter + *iter1 + *iter2;
if(abs(sum-target) < abs(result-target))
{
result = sum;
if(sum == target)
return sum;
}
if(sum>target) //目的是接近target
iter2--;
else if(sum<target)
iter1++;
else
return result;
}
}
return result;
}