剑指 Offer 57. 和为s的两个数字
Posted aaaaaaaWoLan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 57. 和为s的两个数字相关的知识,希望对你有一定的参考价值。
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
思路一:二分查找,遍历数组元素,遍历时得到target与每个元素的差值,再用二分查找在数组里从当前元素开始向后找差值。
假设某个数组元素为nums[i],差值founder = target - num[i],左边界为nums[i],向后查找founder。因为nums[i]之前的元素都已经被遍历过了,founder如果存在,不可能在nums[i]之前。
在二分查找函数里用一个布尔变量flag来判断是否找到了founder,找到了返回founder,否则返回-1(数组元素大于等于1)
时间复杂度:O(N*logN)
代码:
int BinarySearch(int*nums, int begin, int numsSize, int target, bool flag)
{
int mid = begin + (end - begin) / 2;
while (begin <= end)
{
mid = begin + (end - begin) / 2;
if (nums[mid] > target)
{
end = mid - 1;
}
else if (nums[mid] < target)
{
begin = mid + 1;
}
else
{
flag = true;
break;
}
}
if (flag == true)
{
return nums[mid];
}
else
{
return -1;
}
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
if (numsSize == 0)
{
*returnSize = 0;
return NULL;
}
int result = 0;
int i = 0;
while (i < numsSize)
{
printf("%d ", i);
int founder = target - nums[i];
//如果target与当前数组元素的值小于该数组元素,说明找不到这样的两个元素
if (founder < nums[i])
{
*returnSize = 0;
return NULL;
}
else
{
result = BinarySearch(nums, i, numsSize, founder, false);
if (result == -1)//没找到,继续查找
{
i++;
continue;
}
else//找到了
{
break;
}
}
}
//循环结束还没有找到
if (result == -1)
{
*returnSize = 0;
return NULL;
}
*returnSize = 2;
int*ret = (int*)malloc(sizeof(int) * (*returnSize));
ret[0] = nums[i];
ret[1] = result;
return ret;
}
自认为这个时间复杂度已经够快了,直到看到题解里的双指针、哈希表(只会用C的菜鸡还不懂哈希表)…
**思路二:**双指针遍历,一个指针指向数组左边界,一个指向右边界,类似二分思想
- 当左指针元素与右指针元素之和大于target时,右指针向左走一步
- 当两者之和小于target时,左指针向右走一步
代码:
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
if (numsSize == 0)
{
*returnSize = 0;
return NULL;
}
int left = 0;
int right = numsSize - 1;
*returnSize = 2;
int*ret = (int*)malloc(sizeof(int) * (*returnSize));
while (left <= right)
{
if (nums[left] + nums[right] > target)//和偏大
right--;
else if (nums[left] + nums[right] < target)//和偏小
left++;
else//找到了
{
ret[0] = nums[left];
ret[1] = nums[right];
return ret;
}
}
//出循环了说明没有找到
*returnSize = 0;
return NULL;
}
以上是关于剑指 Offer 57. 和为s的两个数字的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode(剑指 Offer)- 57. 和为 s 的两个数字
LeetCode(剑指 Offer)- 57. 和为 s 的两个数字