双指针
整理来自:算法一招鲜——双指针问题 - 知乎 (zhihu.com)
对撞指针:
用于有序数组,左侧索引定义为左指针(Left),右指针定义为(Right),从两头向中间遍历。
例题:举个LeetCode上的例子:
以LeetCode 881救生艇问题为例
由于本题只要求计算出最小船数,所以原数组是否被改变,和元素索引位置都不考虑在内,所以可以先对于给定数组进行排序,再从数组两侧向中间遍历。所以解题思路如下:
对给定数组进行升序排序
初始化左右指针
每次都用一个”最重的“和一个”最轻的“进行配对,如果二人重量小于Limit,则此时的”最轻的“上船,即(left++)。不管”最轻的“是否上船,”最重的“都要上船,即(right--)并且所需船数量加一,即(num++)
代码如下:
var numRescueBoats =function(people, limit) {
people.sort((a, b) => (a -b));
var num =0
let left =0
let right = people.length-1
while (left <= right){
if ((people[left] +people[right]) <= limit) {
left++
}
right--
num++
}
return num
};
快慢指针:
两个指针从同一侧开始遍历,快指针(fast),慢指针(slow)。
用于判断链表是否有环,快指针每次增加两个,慢指针每次增加一个,如果慢指针遇到快指针则说明有环。
例题:
稳定排序
再比如LeetCode26 删除排序数组中的重复项,这里还是定义快慢两个指针。快指针每次增长一个,慢指针只有当快慢指针上的值不同时,才增长一个(由于是有序数组,快慢指针值不等说明找到了新值)。
真实代码:
var removeDuplicates = function (nums) {
if (nums.length === 0) {
return 0;
}
let slow = 0;
for (let fast = 0; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;
};