代码随想录第2天 | 977. 有序数组的平方、209. 长度最小的子数组、59. 螺旋矩阵II

977. 有序数组的平方

  1. 暴力解法
    foreach遍历每个数组平方,再进行排序。
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    nums.forEach((value, index, arr) => {
        arr[index] = value * value;
    })
    nums.sort((a, b) => {
        if(a < b) return -1;
        if(a > b) return 1;
        return 0;
    })
    return nums;
};
  1. 双指针法
    一个指向起始位置,一个指向终止位置。在新数组上的指针指向终止位置,达到从小到大排列的目的。
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function (nums) {
    let n = nums.length;
    let res = new Array(n);
    let i = 0, j = k = n - 1;
    while (i <= j) {
        if(nums[i] * nums[i] > nums[j] * nums[j]){
            res[k--] = nums[i] * nums[i];
            i++;
        }
        else{
            res[k--] = nums[j] * nums[j];
            j--;
        }
    }
    return res
};

209. 长度最小的子数组

滑动窗口法:不断调节子序列的起始位置和终止位置。

需要考虑的问题:如果只用一个for循环的话,该指向起始位置还是终止位置。如果指向起始位置的话,就和两个for一样了。所以只用一个for循环,那么这个循环的索引,一定是表示滑动窗口的终止位置

在每次向后移动滑动的时候,窗口内的总和和target作比较,一旦大于等于了target,也就说明需要缩小滑动窗口了,此时比较下滑动窗口的长度。在缩小滑动窗口后,如果小于target,那么就向后移动指针移动滑动窗口。

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let start = end = 0;
    let sum = 0;
    let ans = Infinity;
    while(end < nums.length){
        sum += nums[end];
        while(sum >= target){
            let len = end-start+1;
            ans = Math.min(ans, len);
            sum -= nums[start];
            start++;
        }
        end++;
    }
    return ans === Infinity ? 0: ans;
};

59. 螺旋矩阵II

依旧遵循循环不变量的原则。

要确定遍历每一条边的循环条件,同样可以选择左闭右开或左开右闭。同时也要注意n的大小决定了矩阵需要转多少圈以及矩阵中间是否会多出单独一个值。

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function (n) {
    let startX = startY = 0;
    let loop = Math.floor(n / 2);
    let mid = Math.floor(n / 2);
    let offset = 1;
    let count = 1;
    let result = new Array(n).fill(0).map(() => new Array(n).fill(0));
    while (loop--) {
        let i = startX, j = startY;
        for (; j < startY + n - offset; j++) {
            result[i][j] = count++;
        }
        for(; i < startX + n - offset; i++) {
            result[i][j] = count++;
        }
        for(; j > startY; j--){
            result[i][j] = count++;
        }
        for(; i > startX; i--){
            result[i][j] = count++;
        }
        startX++;
        startY++;
        offset += 2;
    }
    if(n%2 != 0){
        result[mid][mid] = count;
    }
    return result;
};

数组篇总结

  1. 循环不变量原则:左闭右开等等。
  2. 双指针法:通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
  3. 滑动窗口:根据当前子序列和大小的情况,不断调节子序列的起始位置或终止位置。

你可能感兴趣的:(算法,数据结构,js)