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

40 阅读3分钟

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]

思路

1.暴力解法:每个数平方之后,再排序。

时间复杂度 O(n + nlogn)   空间复杂度 O(1)

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var search = function(nums, target) {
    const arr = nums.map((num, i)=>{
        return num*num
    })
    arr.sort((a,b)=>(a-b))
    return arr
};

2.双指针法:数组是有序的,所以平方之后的最大值不是在数组左边的负数,就是在数组右边,因此采用双指针法,i指向起始位置,j指向终止位置

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

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var sortedSquares = function(nums) {
    //双指针法
    let i=0, j=nums.length-1
    let res = []
    while(i<=j){
        if(nums[i]*nums[i]<nums[j]*nums[j]){
            res.unshift(nums[j]*nums[j])
            j--
        }else{
            res.unshift(nums[i]*nums[i])
            i++
        }
    }
    return res
};

209. 长度最小的子数组

题目链接

要求: 给定一个含有 n ****个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 ****target ****的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度 如果不存在符合条件的子数组,返回 0 。

image.png

思路

  1. 暴力解法:两个for循环(超时)

时间复杂度  O(n^n)   空间复杂度  O(1)

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let len = Infinity //最后输入子数组的最小长度
    for(let i=0 ; i<=nums.length;i++){ //设置子序列起点i
        let sum = 0 //子序列的数值之和
        for(let j=i; j<nums.length; j++){ ////设置子序列终点i
            sum += nums[j]
            if(sum>=target){ 
                len = Math.min(len, j-i+1) //获取子序列的最小长度
                break
            }
        }
    }
    return len != Infinity ? len : 0
};

2.滑动窗口:一个for循环

窗口: 满足其和 ≥ target 的长度最小的连续子数组。

窗口的起始位置如何移动:如果当前窗口的值大于target,要更新子序列的最小长度,且窗口需要向前移动。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

时间复杂度  O(n^n)   空间复杂度  O(1)

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

59. 螺旋矩阵 II

题目链接

时间复杂度  O(n^2)   空间复杂度 O(1)

#类似题目

要求: 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

image.png

思路

模拟顺时针画矩阵的过程,注意循环条件,每次一条边遍历完毕后,要判断是否超出。

/**
 * @param {number} n
 * @return {number[][]}
 */
var generateMatrix = function(n) {
    let top = 0, bottom = n-1, left = 0, right = n-1
    let res = Array(n).fill(0).map(()=>Array(n).fill(0))
    let count = 1
    while(n--){
        for(let i=left; i<=right; i++){
             res[top][i] = count++
        }
        top++
        if(top>bottom) break
        for(let i=top; i<=bottom; i++){
            res[i][right] = count++
        }
        right--
        if(left>right) break
        for(let i=right; i>=left; i--){
            res[bottom][i] = count++
        }
        bottom--
        if(top>bottom)break
        for(let i=bottom; i>=top; i--){
            res[i][left] = count++
        }
        left++
        if(left>right) break
    }
    return res
};