😍代码展示:
public int removeDuplicates(int[] nums) { int n = nums.length; if (n == 0) { return 0; } int fast = 1, slow = 1; while (fast < n) { if (nums[fast] != nums[fast - 1]) { nums[slow] = nums[fast]; ++slow; } ++fast; } return slow; }
🎨 2.相向左右双指针
前面一种是同向的双指针,下面这种是相向的双指针,也就是一左一右的左右指针,前一种通常是快指针遍历完则结束循环得到答案。而这种相向通常是左右指针满足某种条件时或者两者相遇时结束循环,去感受两者的区别和魅力
🌞 删除有序数组的重复项
题目:给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
给上题目链接:两数之和||——输入有序数组https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/
💚 思路:因为我们需要找到两个数相加等于目标数target,因为数组是一个非递减的数组,所以当我们的两个指针指向数组的两端,此时他们相加有一个和我们设为sum。如果左指针向右移动,右指针不动,此时sum要么不变要么变大,不可能变小,因为数组是非递减的。反之如果右指针向左移动,左指针不动时,sum要么变小要么不变。那每次我们对sum和target进行比较,如果sum小于target,我们是不是需要让sum变大?那我们把左指针右移一位继续判断,sum还小与target,左指针就继续移。当突然发现sum一下变得比target大了,我们就需要把右指针左移,让sum变小,就在这不断的平衡中,终有两个位置,使得sum等于target,就是此时两指针的位置。因为题目说了仅存在一个有效答案,如果没有我们就返回两个-1即可。
❤️ 核心:通过判断左右指针之和与target的大小关系,来判断是哪个指针向中间移动
😍代码展示:
public int[] twoSum(int[] numbers, int target) { int left= 0, right= numbers.length - 1; while (left< right) { int sum = numbers[left] + numbers[right]; if (sum == target) { return new int[]{left+ 1, right+ 1}; } else if (sum < target) { ++left; } else { --right; } } return new int[]{-1, -1}; }
🌳4.双指针总结
🏆总结:双指针的使用场景大致就分为这两种,其实类似我们小学学的汽车问题,有的是向同一头出发,有的是相向而行,具体使用哪种双指针需要我们进行判断,当然这种判断的能力建立在我们大量的练题基础上,这里我只是列举了两种情况比较简单的举例,方便大家理解,下面是力扣双指针模块的练习题,从简入手,学会总结,学会双指针就算是真正的入门算法,成为了一名合格的算法小白