算法打卡第二天 数组2 JS

68 阅读2分钟

977.有序数组的平方

一看到是有序数组,并且求平方后排序,我直接啪的很快就是:

var sortedSquares = function(nums) {
    let result = [];
    for (let i = 0; i < nums.length; i++) {
        result[i] = nums[i] * nums[i];
    }
    result.sort((a,b)=> a - b);
    return result;
};

循环求平方值后,重新排序,然后一看题目要求O(n)的时间度,我傻眼了。 然后才有了下面的解法。

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    let result = [];
    // 因为nums是非递减数组,而且求的是值平方,所以可以考虑使用左右2指针,往中间遍历
    let i = 0, j = nums.length - 1;
    // K是结果数组result的下标,如果从0开始,最后还得重新排序一次
    let k = nums.length - 1;
    while (i <= j) {
        // 对比左指针平方的值,和右指针平方的值,赋值到结果数组中,移动对应指针
        // 左指针比右指针的平方值小时候,赋值后,移动右指针
        if (nums[i] * nums[i] < nums[j] * nums[j]) {
            result[k--] = nums[j] * nums[j]; 
             j--;
        // 右指针比左指针的平方值小时候,赋值后,移动左指针
        } else  {
            result[k--] = nums[i] * nums[i];
            i++;
        }
    }
    return result;
};

209.长度最小的子数组

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    // 采用滑动窗口的思想,一旦窗口内的总值大于target,就收缩窗口,左指针向右移动。
    // 不断对比窗口内的最小子数组个数。
    let l = 0;
    let sum = 0;
    let ans = Infinity;
    for (let i = 0; i < nums.length; i++) {
        sum+= nums[i];
        while (sum >= target) {
            ans = Math.min(i - l + 1, ans);
            sum -= nums[l];
            l++;
        }
    }
    if (ans == Infinity) {
        return 0
    } else {
        return ans
    }
};

59. 螺旋矩阵 II

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    const matrix = new Array(n).fill(0).map(() => new Array(n).fill(0));
    // 定义初始row,col循坏的初始下表
    let startR = 0,startC = 0;
    // 确认循坏的次数,向下取整如果n是奇数时候,可以少循坏一次
    let loop = mid = Math.floor(n / 2);
    let count = 1;
    let offset = 1;
    while(loop--) {
        // 每循坏一圈更新,row,col的循坏下标
        let row = startR, col = startC;
        // 每一圈的上边循坏赋值
        for (;col < n - offset; col++) {
            matrix[row][col] = count++
        }
        // 每一圈的右边循环赋值
        for (;row < n - offset; row++) {
            matrix[row][col] = count++;
        }
        // 每一圈的下边循环赋值
        for (;col > startC; col--) {
            matrix[row][col] = count++
        }
        // 每一圈的左边循环赋值
        for (;row > startR; row--) {
            matrix[row][col] = count++;
        }
        startR++;
        startC++;
        offset++;
    }
    // 矩阵n如果是奇数,需要补上最后一个数的值
    if (n % 2 == 1) {
        matrix[mid][mid] = count
    }

    return matrix;
}

两天算法总结,数组类型的题目。

如果是查找其中某个值,或者插入值,如果是有序数组,可以考虑二分法解题。

如果是在原数组中修改数组,可以考虑双指针,快慢指针的方法解题。

螺旋数组的题目,需要考虑循坏边界问题。

求最大子数组,或者最小子数组,可以采用滑动窗口,逐渐扩大,缩小窗口。