这道题目粗看不难,可以直接用个两重循环来找,O(n^2)复杂度,估计超时,因为AC率好像不高。。
然后我再想了一下,又是一个刮三的算法,先排序,然后利用有序的特点,对于每个元素,从剩下的有序元素找到差值等于traget-a[i]的,立即想到二分查找,找不到就进入下一轮外层循环,找到了还要找回原vector所在元素的index,目前没啥好办法,只有遍历了,不过这个遍历只有一次,因此时间复杂度还是之前的O(nlogn).
另外此处还出现了一个问题,就是如果最后找到了两个数相同,那么在找原index的时候,可能会找到一起,因此这里要小心处理 第一次submit就挂了,还好他会说哪个case错了,如果ACM的话,我还要自己去想exception case T T。。。所以我的做法是其中一个index只赋值一次,并且后面准备插vector的时候,要两个index相同。
修改一次之后的代码如下:
vector<int> twoSum(vector<int> &numbers, int target) {
vector<int> vec,copy_numbers=numbers;
sort(numbers.begin(),numbers.end());
int index1=-1,index2=-1;
for(int i=0;i<numbers.size();i++)
{
int low=i+1,high=numbers.size()-1;
int query=target-numbers.at(i);
while(low<=high)//binary search
{
int mid=(low+high)/2;
if(query<numbers.at(mid))
high=mid-1;
else if(query>numbers.at(mid))
low=mid+1;
else
{
for(int k=0;k<numbers.size();k++)//find raw index
{
if(index1==-1&©_numbers.at(k)==numbers.at(i))//此处index1==-1 表示第一次找到以后就不再找第一个数在原数组的index了,因为可能再往后,然后又和index2 collision了,导致最后明明有答案,但是没找到,例如[0,0,3,4] 0 如果不index1==-1 先找index1 index2 都找到0,然后又都找到1 再往后就找不到了。
index1=k;
if(copy_numbers.at(k)==numbers.at(mid))
index2=k;
if(index1!=-1&&index2!=-1&&index1!=index2)//都找到了,并且不同
{
if(index1<index2)
{
vec.push_back(index1+1);
vec.push_back(index2+1);
}
else
{
vec.push_back(index2+1);
vec.push_back(index1+1);
}
return vec;
}
}
}
}
continue;
}
/* for(int j=i+1;j<numbers.size();j++)
{
//if(numbers.at(i)+numbers.at(j)>target)
// break;
if(numbers.at(i)+numbers.at(j)==target)
{
vec.push_back(i+1);
vec.push_back(j+1);
return vec;
}
}*/
}