LeetCode刷题——算法学习计划(入门部分)
题目描述
思路介绍
这道题我采用了双指针法
,虽说叫双指针,但其实没用到指针:定义两个整数,一个指向数组头部,一个指向尾部,如果这两个下标对应的数组值之和等于目标值,则返回这两个下标;如果它们的和小于目标值,指向左下标的整数left
向右移;如果它们的和大于目标值,指向右下标的整数right
向左移。由于题目要求返回的下标从1开始,所以记得将返回的下标加上1。
当然,官方题解中还用到了二分法,具体实现见官方题解(下文)。
我的第一次正确提交
本次提交使用到了双指针法
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize)
{
int left = 0;
int right = numbersSize - 1;
int *returnNumbers = (int*)malloc(sizeof(int) * 2);
while(left < right)
{
if(numbers[left] + numbers[right] == target)
{
*returnSize = 0;
returnNumbers[(*returnSize)++] = left + 1;
returnNumbers[(*returnSize)++] = right + 1;
return returnNumbers;
}
else if(numbers[left] + numbers[right] > target)
{
right--;
}
else
{
left++;
}
}
return returnNumbers;
}
官方版本
下面是官方版本
方法一:二分查找
在数组中找到两个数,使得它们的和等于目标值,可以首先固定第一个数,然后寻找第二个数,第二个数等于目标值减去第一个数的差。利用数组的有序性质,可以通过二分查找的方法寻找第二个数。为了避免重复寻找,在寻找第二个数时,只在第一个数的右侧寻找。
——作者:LeetCode-Solution
感觉很玄妙
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int* ret = (int*)malloc(sizeof(int) * 2);
*returnSize = 2;
for (int i = 0; i < numbersSize; ++i) {
int low = i + 1, high = numbersSize - 1;
while (low <= high) {
int mid = (high - low) / 2 + low;
if (numbers[mid] == target - numbers[i]) {
ret[0] = i + 1, ret[1] = mid + 1;
return ret;
} else if (numbers[mid] > target - numbers[i]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
}
ret[0] = -1, ret[1] = -1;
return ret;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/liang-shu-zhi-he-ii-shu-ru-you-xu-shu-zu-by-leet-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(nlogn),其中 n 是数组的长度。需要遍历数组一次确定第一个数,时间复杂度是 O(n),寻找第二个数使用二分查找,时间复杂度是 O(logn),因此总时间复杂度是O(nlogn)。
空间复杂度:O(1)。
作者:LeetCode-Solution
方法二:双指针
初始时两个指针分别指向第一个元素位置和最后一个元素的位置。每次计算两个指针指向的两个元素之和,并和目标值比较。如果两个元素之和等于目标值,则发现了唯一解。如果两个元素之和小于目标值,则将左侧指针右移一位。如果两个元素之和大于目标值,则将右侧指针左移一位。移动指针之后,重复上述操作,直到找到答案。
——作者:LeetCode-Solution
上面是官方题解
毕竟我和官方都用的双指针,所以代码上没有太大区别
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int* ret = (int*)malloc(sizeof(int) * 2);
*returnSize = 2;
int low = 0, high = numbersSize - 1;
while (low < high) {
int sum = numbers[low] + numbers[high];
if (sum == target) {
ret[0] = low + 1, ret[1] = high + 1;
return ret;
} else if (sum < target) {
++low;
} else {
--high;
}
}
ret[0] = -1, ret[1] = -1;
return ret;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/liang-shu-zhi-he-ii-shu-ru-you-xu-shu-zu-by-leet-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(n),其中 n 是数组的长度。两个指针移动的总次数最多为 n 次。
空间复杂度:O(1)。
——作者:LeetCode-Solution