力扣刷题-双指针法

126 阅读3分钟

双指针法是处理数组、字符串问题常用的算法。

先用题目引入: 27.移除元素

给你一个数组 nums ,移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并修改输入数组**。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

暴力解法

首先可以用暴力解法:用两层循环:外层循环用于遍历数组找到数值等于val的元素,内层循环从该元素开始后一位元素提前一位,即数值等于val的元素会被其后一位覆盖。

Js代码如下:

var removeElement = function(nums, val) {
    var size=nums.length;
    var i=0;
    while(i<size){
        if(nums[i]==val){
            for(var k=i;k<size-1;k++){
                nums[k]=nums[k+1];
            }        
            size=size-1;
            i=0; 
        }
        else i++;
    }
    return size;
};

双指针法

使用双指针法可以降时间复杂度为O(n):快指针用于甄别数值等于val的元素,慢指针指向要更新的位置。 代码:i为快指针,只要找到不需要移除的元素,就赋值给k(慢指针)所在位置的元素,而后k增加用于更新下一个元素。

var removeElement = (nums, val) => {
    let k = 0;
    for(let i = 0;i < nums.length;i++){
        if(nums[i] != val){
            nums[k++] = nums[i]
        }
    }
    return k;
};

相关问题

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

思路:因为题目中是非严格递增数组,所以判断是否重复只需要前后比较。快指针找到不与前面重复的元素,将其赋值给慢指针自增后指向的索引位置。

var removeDuplicates = function(nums) {
    var k=0;
    for(var i=1;i<nums.length;i++){
        if(nums[k]!=nums[i]){
            nums[++k]=nums[i];
        }
    }
    return k+1;
};

283.移动零

思路:由于题目要求所有的零移到最后面,不改变其他元素顺序,所以用快指针来指向不是0的元素,慢指针指向0元素,当该条件发生时,两个元素互换位置(将0换到后面),慢指针前进一位。

var moveZeroes = function(nums) {
    var k=0;
    for(var i=1;i<nums.length;i++){
        if(nums[k]==0 && nums[i]!=0){
            var temp=nums[k];
            nums[k]=nums[i];
            nums[i]=temp;
            k++;
        }
        else if(nums[k]!=0) k++;
    }
    return nums;
};

844.含退格的字符串

思路:1.字符串不能像数组一样通过索引修改单个字符值,所以要先将其转换成数组。2.用下标-1实现“退格”动作。3.注意由于快指针是从1开始的,所以要先对最开头是退格符的情况作处理。4.对处理后返回的新数组和实际长度(k1,k2),判断是否一致。

function dealWithArray(arr){
    var k=0;
    if(arr[0]=='#'){
        arr[0]=null;
        k=-1;
    }
    for(var i=1;i<arr.length;i++){
        if(arr[i]!='#'){
            k++;
            arr[k]=arr[i];
            
        }
        else{
            if(k>0) k--;
            else {
                arr[0]=null;
                k=-1;
            }
        }
    }
    return k;
}

var backspaceCompare = function(s, t) {
    var s_arr=s.split('');
    var t_arr=t.split('');
    var k1=dealWithArray(s_arr);
    var k2=dealWithArray(t_arr);
    
    if(k1!=k2) return false;
    else{
        if(k1==-1) return true;
        for(var i=0;i<=k1;i++){          
            if(s_arr[i]!=t_arr[i]) return false;
        }
        return true;
    }

};