1.题目
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
- 返回的下标值(index1 和 index2)不是从零开始的。
- 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
题目来源:力扣(LeetCode)戳我前往
2.题目分析
题目看起来很简单,但是暴力枚举肯定是会超时的。刚开始我也是暴力枚举了一下,一个指针从前,一个从后开始遍历,O[n²]的时间复杂度不是吹的,直接超时了。
这时候就可以考虑一下查找,因为给定数组的有序的,所以可以考虑用查找的方法。
先从前往后遍历数组,假装确定了index1,那么index2我们就可以用target-index1在数组右边找。因为是顺序表,那我们就可以首先考虑查找里面的二分法查找。
3.代码实现
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
int rem,mid,low,high,i;
int* ret = (int*)malloc(sizeof(int) * 2);//定义的返回数组
*returnSize = 2;
for(i=0;i<numbersSize;i++)
{
rem = target-numbers[i];
low = i+1;
high = numbersSize-1;
while(low<=high)
{
mid = (high + low) / 2;
if(rem == numbers[mid])
{
ret[0] = i+1;//通过样例可以看出,要加1
ret[1] = mid+1;
return ret;
}
else if(rem<numbers[mid])
high = mid-1;
else
low = mid+1;
}
}
ret[0] = -1;
ret[1] = -1;
return ret;
}