LeetCode 20天算法刷题计划第三天:双指针
Posted lxkeepcoding
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 20天算法刷题计划第三天:双指针相关的知识,希望对你有一定的参考价值。
目录
前言
hello,大家好,这篇博客来介绍LeetCode 20天算法刷题计划(点击跳转LeetCode20天算法刷题计划)第三天的两道题目。用到的知识点还是双指针。由于博主个人的懒惰,刷题计划并没有每天坚持,虽然内心好像是充满了愧疚,但还是要继续懒惰下去哈。
好啦,闲言少叙,让我们开始这篇博客。
1. 283移动零
1.1 题目链接
https://leetcode-cn.com/problems/move-zeroes/
1.2 题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
1.3 题目分析
看到这道题我们首先可以考虑双指针,左指针指向头部,右指针指向尾部。右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。这样就可以完成交换啦。在这个过程中,左指针以左始终是非0,右指针以右始终是0,在交换过程中,是左指针指向的0元素与右指针指向的非0元素交换。我们来看一下动图演示(第一次做动图,质量略显粗糙)
除了这种做法,我们还可以用补0的方法做,也就是说,我们从头遍历这个数组,遇到0我们跳过去,同时我们要记住跳过了几个0,然后将这些跳过的0在结尾补上,这也是一种实现方法。
1.4 代码实现
1.4.1 双指针
void swap(int *a, int *b) {
int t = *a;
*a = *b, *b = t;
}
void moveZeroes(int *nums, int numsSize) {
int left = 0, right = 0;
while (right < numsSize) {
if (nums[right]) {
swap(nums + left, nums + right);
left++;
}
right++;
}
}
1.4.2 尾部补0
class Solution {
public void moveZeroes(int[] nums) {
int indexNow = 0;
int indexNum = 0;
int m = nums.length;
while(indexNum<m){
if(nums[indexNum] != 0) {
nums[indexNow++] = nums[indexNum];
}
++indexNum;
}
for(int i = indexNow; i < m; i++){
nums[i] = 0;
}
}
}
2. 167. 两数之和 II - 输入有序数组
2.1 题目链接
https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/
2.2 题目描述
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
2.3 题目分析
数组是升序的,这道题我们也是可以用双指针来解决的。我们依旧设置左指针和右指针。我们让左指针指向的数字和右指针指向的数字相加,如果相加得到的结果大于target,则右指针向左移动,如果小于则左指针向右移动,如果等于则查找成功。
但是有人可能会疑惑,这种做法会不会存在丢解的情况呢?注意,题目中已经告诉我们是存在唯一解的。也就是说,一定是有固定的两个位置的值相加等于target。我们的左指针是从小到大,右指针是从大到小,如果我们跳过了作值为例,那么和这个值匹配能够相加得到target的那个数,一定会比现在右指针指向的那个数大,也就是说,在之前这个数就应该已经和那个数匹配过了,然而并没有,所以这是一个悖论,所以不存在丢解的情况。
2.4 代码实现
nt* 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;
}
后记
好的,这篇博文就到这里了。希望对大家有所帮助。为了更好地完成这篇博客,博主学会了制作动图,成功get新技能。日拱一卒,继续努力。
以上是关于LeetCode 20天算法刷题计划第三天:双指针的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题100天—189. 旋转数组(双指针)—day20
Leetcode刷题100天—283. 移动零(双指针)—day20