五、leetcode - 快慢指针(JS)

206 阅读2分钟

26. 删除有序数组中的重复项

输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。
     不需要考虑数组中超出新长度后面的元素。
              修改前          修改后         修改后的slow
slow=0 fast=0 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=1 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=2 [ 1, 1, 1, 2 ] [ 1, 1, 1, 2 ] slow=0 
slow=0 fast=3 [ 1, 1, 1, 2 ] [ 1, 2, 1, 2 ] slow=1
/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    let slow = 0; // 包括慢指针在内的之前元素都是不重复的
    let fast = 0;
    while(fast < nums.length) {
        console.info('slow='+slow+' fast='+fast);
        console.info(nums);
        if(nums[fast] !== nums[slow]) {
            nums[slow + 1] = nums[fast];
            slow++;
        }
        fast++;
        console.info(nums);
        console.info('slow='+slow);
    }
    return slow + 1; // slow是从0开始的下标,所以长度需要+1
};

27. 移除元素

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

输入: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],也会被视作正确答案。
              修改前          修改后         修改后的slow
slow=0 fast=0 [ 3, 2, 2, 3 ] [ 3, 2, 2, 3 ] slow=0 
slow=0 fast=1 [ 3, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=1 
slow=1 fast=2 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2 
slow=2 fast=3 [ 2, 2, 2, 3 ] [ 2, 2, 2, 3 ] slow=2
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let slow = 0; // 慢指针之前的元素都是移除目标元素的
    let fast = 0;
    while(fast < nums.length) {
        console.info('slow='+slow+' fast='+fast);
        console.info(nums);
        if(nums[fast] !== val){
            nums[slow] = nums[fast];
            slow++;
        }
        fast++;
        console.info(nums);
        console.info('slow='+slow);
    }
    return slow;
};

283. 移动零

快慢指针

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let slow = 0;
    for(let i = 0; i < nums.length; i++) {
        if(nums[i] !== 0) {
            [nums[i], nums[slow]] = [nums[slow], nums[i]];
            slow++;
        }
    }
};
              修改前              修改后             修改后的slow
slow=0 fast=0 [ 0, 1, 0, 3, 12 ] [ 0, 1, 0, 3, 12 ] slow=0 
slow=0 fast=1 [ 0, 1, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1 
slow=1 fast=2 [ 1, 0, 0, 3, 12 ] [ 1, 0, 0, 3, 12 ] slow=1 
slow=1 fast=3 [ 1, 0, 0, 3, 12 ] [ 1, 3, 0, 0, 12 ] slow=2 
slow=2 fast=4 [ 1, 3, 0, 0, 12 ] [ 1, 3, 12, 0, 0 ] slow=3
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let slow = 0;  // 慢指针之前的元素都是不含0元素的
    let fast = 0;
    while(fast < nums.length) {
        if(nums[fast] !== 0) {
            let temp = nums[slow];
            nums[slow] = nums[fast];
            nums[fast] = temp;
            slow++;
        }
        fast++;
    }
};