代码随想录算法训练营DAY 2 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方 

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

示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100]  解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]

示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]

解题: 关键点在于左右两边的值一定会有个最大值,故采用双指针来判断是否哪个值更大,给结果数组倒序赋值 

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    let slow = 0, fast = nums.length-1, len = nums.length-1,result = [];
    while(slow <= fast) {
        let Data1 = nums[slow] * nums[slow]
        let Data2 = nums[fast] * nums[fast]
        if (Data1 > Data2) {
            result[len] = Data1
            slow++
        } else {
            result[len] = Data2
            fast--
        }
        len--
    }
    return result
};

209.长度最小的子数组 

给定一个含有n个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:输入:target = 4, nums = [1,4,4] 输出:1
示例 3:输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0

解题: 暴力解题思路是两个for循环,会导致超时,而应该采用窗口滑动的方式,降低时间复杂度为O(n) 滑动窗口关键点在于确定终点指针和初始指针,先移动终点指针,到了符合条件的位置,开始移动初始指针,并记录当中的符合条件的最小长度,不符合条件后则继续跑终止指针 

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let slow = 0, fast = 0,sum = 0,result= Number.MAX_VALUE;
    for(;fast<nums.length;fast++) {
        sum+=nums[fast]
        while(sum>=target) {
            result = Math.min(result, fast - slow + 1)
            sum-=nums[slow]
            slow++
        }
    }
    return result === Number.MAX_VALUE ? 0 : result
};

59.螺旋矩阵II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:输入:n = 1
输出:[[1]]

解题: 这题需要先创建初始化的数组,找出需要遍历多少圈,针对遍历数对四条边进行循环遍历,以此赋值。 主要难点在于确定边界值,以及循环一圈的固定逻辑怎么确定下来 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值