题目描述:
个人题解:
初始时两个指针分别指向第一个元素位置和最后一个元素的位置。每次计算两个指针指向的两个元素之和,并和目标值比较。如果两个元素之和等于目标值,则发现了唯一解。如果两个元素之和小于目标值,则将左侧指针右移一位。如果两个元素之和大于目标值,则将右侧指针左移一位。移动指针之后,重复上述操作,直到找到答案。
在整个移动过程中,控制左指针不能移到右指针的右侧,右指针不能移到左指针的左侧,因此不会把可能的解过滤掉。由于题目确保有唯一的答案,因此使用双指针一定可以找到答案。
重点:
1.如果左指针先到达下标 i 的位置,此时右指针还在下标 j 的右侧,sum>target,因此一定是右指针左移,左指针不可能移到 i 的右侧。
2.如果右指针先到达下标 j 的位置,此时左指针还在下标 i 的左侧,sum<target,因此一定是左指针右移,右指针不可能移到 j 的左侧。
3.注意if-else if-else的使用。
代码实现:
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int* ret = (int*)malloc(sizeof(int) * 2);
*returnSize = 2;
int left = 0,right = numbersSize-1;
while(left < right)
{
if(numbers[left] + numbers[right] == target)
{
ret[0] = left + 1, ret[1] = right + 1;
return ret;
}
else if(numbers[left] + numbers[right] < target)
left++;
else
right--;
}
ret[0] = -1, ret[1] = -1;
return ret;
}
复杂度分析:
时间复杂度:O(n),其中 n 是数组的长度。两个指针移动的总次数最多为 n 次。
空间复杂度:O(1)。