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]20天算法刷题计划之算法入门

[Leetcode]20天算法刷题计划之算法入门

Leetcode刷题100天—283. 移动零(双指针)—day20

Leetcode刷题100天—283. 移动零(双指针)—day20

Leetcode刷题100天—977. 有序数组的平方(双指针)—day20