狂刷力扣之双指针法

129 阅读2分钟

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

1639575647(1).jpg

可用题型

  • 移除元素
  • 有序数组(含有负数)的平方排序
  • (未完待续...)

复杂度

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

上力扣!

  1. 力扣链接:移除元素

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

JS代码:

var removeElement = function(nums, val) {
    let slow=0;
    for(let fast=0; fast<nums.length; fast++) {
        if(nums[fast]!=val) {
            nums[slow++] = nums[fast]
        }
    }
    return slow
};
  1. 力扣链接:移动零

题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

JS代码:

var moveZeroes = function(nums) {
    let slow = 0;
    for(let fast = 0; fast < nums.length; fast++) {
        if(nums[fast] != 0) {
            nums[slow++] = nums[fast];
        }          
    }  

    for (let i = slow; i < nums.length; i++) {
            nums[i] = 0
        }
};
  1. 力扣链接: 有序数组平方排序

题目描述:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

const sortedSquares = function (nums) {
    let res = []
    for (let i = 0, j = nums.length - 1; i <= j;) {
      const left = Math.abs(nums[i])
      const right = Math.abs(nums[j])
      if (right > left) {
        // push element to the front of the array
        res.unshift(right * right)
        j--
      } else {
        res.unshift(left * left)
        i++
      }
    }
    return res
  }

ps:看这个代码风格,有没有人发现这个代码和之前的不太一样,因为不是我写的。我的代码输入进去提交,显示输出超出限制,但是在控制台是可以输出答案的,这里也先记录一下,后面找找原因。

var sortedSquares = function(nums) {
    let res = [];
    let left = 0, right = nums.length - 1;
    while (left <= right) {
        if (Math.abs(nums[left]) > Math.abs(nums[right])) {
            res.unshift(nums[left] * nums[left]);
            console.log(res)
            left ++;
        } else {
            res.unshift(nums[right] * nums[right]);
            right --;
        }
    }
    return res;
};
  1. 力扣链接: 长度最小的子数组

题目描述:给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

var minSubArrayLen = function(target, nums) {
    let left = 0, right = 0, sum = nums[0];
    let resLen = nums.length + 1, newLen = 0;
    if (nums[0] >= target) return 1;
    while (sum < target) {
        right ++;  
        if (right == nums.length && left == 0) return 0;
        sum += nums[right]; 
     while (sum >= target) {     
            newLen = right - left + 1; 
            resLen = newLen < resLen ? newLen : resLen; 
            sum -= nums[left];     
            left ++;
        }
    }
    return resLen;
};

本题实际上是使用了滑动窗口的这个方法:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果