第三天(双指针)
移动零
283. 移动零 - 力扣(LeetCode)
使用快慢两指针, 慢指针每当快指针找到非零内容时两者数值进行交换慢指针后移,我们的快指针遍历完数值即可结束.
void Swap(int*a ,int* b) { int tmp = *a; *a = *b; *b = tmp; } void moveZeroes(int* nums, int numsSize) { int fast = 0; int slow = 0; while(fast < numsSize) { if(nums[fast] != 0) { Swap(nums+fast,nums+slow); slow++; } fast++; } }
两数之和
167. 两数之和 II - 输入有序数组 - 力扣(LeetCode)
注:本次讲解的案例都来自力扣题解,博主只是为了做笔记方便后续查看.
方法一(二分查找)
既然是有序的了我们也别浪费,虽然他是查找两个数看似没有通过mid来排除的条件但是我们可以先固定一个数在通过二分查找找固定值的方式来进行查找,如果固定值没有那就找下一个=.=
代码如下
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) { *returnSize = 2; int* ret = (int*)malloc(sizeof(int)*(*returnSize)); for(int i = 0;i < numbersSize; i++)//以i为目标找target-numsber[i]的值. { int low = i + 1, hight = numbersSize - 1;//low为i+1是为了将i排除(看题) while(low <= hight) { int mid = (low+hight) / 2; if(numbers[mid] < target - numbers[i]) { low = mid + 1; } else if(numbers[mid] > target - numbers[i]) { hight = mid - 1; } else { ret[0] = i + 1; ret[1] = mid+1; return ret; } } } //没找到. ret[0] = -1; ret[1] = -1; return ret; }
方法二(双指针)
双指针思路也很简单,因为数组是有序的所以我们可以计算最左和最右的和与目标值进行比较,如果比目标值大就右边向左走一步,比目标值小就左指针想右走步.直到找到值或left和right相遇.
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) { int left = 0; int right = numbersSize - 1; *returnSize = 2; int* ret = (int*)malloc(sizeof(int)*(*returnSize)); while(left < right) { int sum = numbers[left]+numbers[right]; if(sum > target) { right--; } else if(sum < target) { left++; } else { ret[0] = left+1; ret[1] = right+1; return ret; } } ret[0] = -1; ret[1] = -1; return ret; }