• 【LeetCode】——双指针(快慢指针)/多指针


     =========================================================================

    个人主页

    代码仓库

    C语言专栏

    初阶数据结构专栏

    Linux专栏

    =========================================================================


    前言

    大家好!这是新开的LeetCode刷题专栏,这个专栏不只是随便的拿一些我练过的题讲解,而是总结我在刷题中的一些方法适用于一大类的题,是给大家提供这一大类题的解题方法或者思路,希望能给一些刚开始刷题的小白提供帮助,防止他们在刚开始刷题时,由于LeetCode的难度而从入门到入土,从而放弃,刚开始也是使用最基础的C语言来讲解。

    第一期,今天给大家带来的是双指针也可以叫做快慢指针,甚至是多指针,这种解题方法大多适用于对数组中数的操作,移动、删除等等。话不多说让我们开始刷题吧!

    LeetCode 26.删除数组中的重复项

    OJ链接

    题目描述:

    给你一个 非严格递增排列 的数组 nums ,请你原地删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

    考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

    • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
    • 返回 k 。

    示例 1:

    输入:nums = [1,1,2] 输出:2, nums = [1,2,_]

    解释:函数应该返回新的长度 2 ,并且原数组nums的前面两个元素被修改为 1,2 .不需要考虑数组中超出新长度后面的元素
    示例 2:
    输入:
    nums = [0,0,1,1,1,2,2,3,3,4]

    输出:5, nums = [0,1,2,3,4]

    解释:函数因该返回新的长度 5 ,并且原数组nums的前五个元素被修改为 0, 1,2,3,4。不需要考虑数组中超出新长度后面的元素。

    审题总结:给你一个数组,删除这个数组中相同的元素,并且返回数组的长度。

    思路讲解:

    解法:开辟两个指针都指向头,一个指针先向后移动并和前面的数比较判断,如果前一个指针指向的值和后一个指针指向的值相等,后一个指针向前移动一位,然后前指针继续移动,直到和后一个指针的值不相等时,将前一个指针的值赋给后一个指针的值,后一个指针向前移动,重复前面的操作直到遍历整个数组,这时后一个指针指向数组最后一个数据,返回这个数组的值加1便是数组的长度。

    接口代码

    1. int left=0;
    2. int right=0;
    3. while(right<numsSize)
    4. {
    5. if(nums[right]==nums[left])
    6. {
    7. right++;
    8. }
    9. else
    10. {
    11. left++;
    12. nums[left]=nums[right];
    13. }
    14. }
    15. return left+1;

     LeetCode 27.移除元素

    OJ链接

    题目描述: 

    给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。

    注意:不要使用额外的数组空间,你仅需使用O(1)额外空间并原地修改输入的数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素

    示例 1:

    输入:nums = [3,2,2,3], val = 3

    输出:2, nums = [2,2]

    解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

    示例 2:

    输入:nums = [0,1,2,2,3,0,4,2], val = 2

    输出:5, nums = [0,1,4,0,3]

    解释:函数应该返回新的长度5,并且nums中的前五个元素为0,1,3,0 ,4。注意这五个元素可以为任意顺序。你不需要考虑数组中超出新长度后面的元素。

    审题总结:给你一个数组和一个值,删除这个数组中和这个值相同的元素,并返回数组的长度。

    思路讲解:

    解法一:创建新数组

    首先我们就会想到创建一个新数组,通过遍历原数组中的值将和val不相等的值放到新数组中,但是这种思路的空间复杂度为O(N),和题目要求的空间复杂度O(1)不符合,因此这种思路在这道题行不通。

    解法二:双指针(快慢指针)

    在一开始定义两个指针指向数组的头,前指针遍历数组,当前指针的值和val的值不同时,将前指针的值赋给后一个指针,后一个再移动,直到前指针遍历完整个数组,返回后指针。

    接口代码 

    1. int left=0;
    2. int right=0;
    3. for(right=0;right<numsSize;right++)
    4. {
    5. if(nums[right]!=val)
    6. {
    7. nums[left]=nums[right];
    8. left++;
    9. }
    10. }
    11. return left;

    LeetCode 88.合并两个有序数组

    OJ链接

    题目描述: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

    示例 1:

    输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

    输出:[1,2,2,3,5,6]

    解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

    示例 2:

    输入:nums1 = [1], m = 1, nums2 = [], n = 0

    输出:[1]

    解释:需要合并 [1] 和 [] 。 合并结果是 [1] 。

    示例 3:

    输入:nums1 = [0], m = 0, nums2 = [1], n = 1

    输出:[1]

    解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

    审题总结:

    给你两个数组,一个数组的长度等于两个数组中的有效数据之和,将长度短的数组合并到长度长的数组中并排序。

    思路讲解:三指针

    这里我们定义三个指针分别指向长数组中的尾,长数组中最后一个有效数据,段数组中的尾,依次向前移动遍历长数组中的有效数据和短数组中的数据相比较,将较大的值放在长数组中的尾部。

    这里我们还要注意一种特殊情况:如果段数组中的每个值都比长数组中有效数据的值都小的话,长数组中的有效数据移动完了,短数组的尾指针还没有移动,这样我们直接将短数组中的值移动到长数组中就行了。因为题目中已经说了是非递减顺序

    接口代码

    1. int end1=m-1;
    2. int end2=n-1;
    3. int end=m+n-1;
    4. while(end1>=0&&end2>=0)
    5. {
    6. if(nums1[end1]>nums2[end2])
    7. {
    8. nums1[end--]=nums1[end1--];
    9. }
    10. else
    11. {
    12. nums1[end--]=nums2[end2--];
    13. }
    14. }
    15. while(end2>=0)
    16. {
    17. nums1[end--]=nums2[end2--];
    18. }

    这一期的快慢指针的三道题目就讲到这里了,这里只是给大家提供一点刷题的方法思路,希望大家以后再做题过程中可以运用到,当然快慢指针不仅适用于数组的题目,再数据结构的顺序表和链表中也可以用到,也不仅仅是两个指针,甚至可以是很多。

  • 相关阅读:
    一种基于注意机制的快速、鲁棒的混合气体识别和浓度检测算法,配备了具有双损失函数的递归神经网络
    Css基础——Css的定位
    Ps:陷印
    Java项目:学生课堂考勤管理系统(java+SSM+JSP+layui+Mysql)
    比较两个值是否相等
    基于matlab创作简易表白代码
    计算机毕业设计之java+ssm的鲜活农产品销售系统
    功率信号源在超声波及智能骨料损伤监测中的应用
    Redis面试题三(集群)
    联邦学习应用研究现状及发展趋势
  • 原文地址:https://blog.csdn.net/qq_55119554/article/details/133191533