代码随想录 day2 - 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

86 阅读3分钟

977. 有序数组的平方

题目链接

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

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

初始解题思路

解题语言使用的是JavaScript,第一时间想到的操作:

var sortedSquares = function(nums) {
    let arr = nums.map(val => Math.abs(val)).sort((a,b) => a-b).map(val => val*val)
    return arr
};

题解思路:左右双指针法

由于数组按非递减顺序排列,且返回值为每个数的平方。通过观察测试用例可以得到左右两边的绝对值最大,向中间依次递减。

设置左右两个指针分别指向nums数组的首尾,比较其绝对值大小,将大的那一个取平方,放入结果数组;移动指针,依次进行比较,直到 left > right为止

var sortedSquares = function(nums) {
    let len = nums.length
    let res = Array(len)
    let p = len-1
    for(let i=0,j=len-1;i<=j;){
        if(Math.abs(nums[i])>Math.abs(nums[j])){
            res[p] = nums[i]*nums[i]
            i++
        }else{
            res[p] = nums[j]*nums[j]
            j--
        }
        p--
    }
    return res
};

209. 长度最小的子数组

题目链接

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

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

初始解题思路:暴力双循环

暴力双循环,依次求取以s[i]开头的满足target条件的子数组,取最小长度进行比较。

var minSubArrayLen = function(target, nums) {
    let subLength = 0
    let minLen = Number.MAX_SAFE_INTEGER
    let sum

    for(let i= 0;i<nums.length;i++){
        sum = 0
        for(let j=i; j<nums.length; j++){
            sum += nums[j]
            if(sum >= target){
                subLength = j - i + 1 
                minLen = Math.min(minLen,subLength)
                break
            }
        }
    }

    if(minLen !== Number.MAX_SAFE_INTEGER){
        return minLen
    }else{
        return 0
    }
};

更优思路:滑动窗口法

滑动窗口:不断调节子数组的起始位置和结束位置,获取想要的子数组,如同一个窗口在数组上移动,展现给我们需要的子数组。

窗口的起始位置:当前窗口值大于 target, 窗口的起始位置需要向后移

窗口的结束位置:窗口的结束位置遍历到数组末尾时,相应的循环结束

var minSubArrayLen = function(target, nums) {
    let res = Number.MAX_SAFE_INTEGER
    let sum = 0
    let start = 0
    let subLength = 0

    for(let end = 0; end<nums.length;end++){
        //未满足target条件时,移动结束位置,累加 sum
        sum += nums[end]
        while(sum >= target){
            subLength = end - start + 1
            res = Math.min(res,subLength)
            // 当子数组满足target 条件时,滑动窗口的起始位置移动
            sum -= nums[start]
            start ++
        }
    }
    return res==Number.MAX_SAFE_INTEGER ? 0 : res
};

59. 螺旋矩阵 II

题目链接

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

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

初始解法:由 [0,0] 一直向内循环

设定left top bottom right 四个边界值,依次向内进行顺时针螺旋,一次到底。

var generateMatrix = function(n) {
    // let matrix = Array(n).fill(Array(n))
    let matrix = Array(n).fill().map(item => new Array(n))
    let [left,right,top,bottom] = [0,n-1,0,n-1]
    let num = 1
    while(num<=n*n){
        for(let i=left;i<=right;i++){
            matrix[top][i] = num
            num ++
        }
        top ++
        if(top > bottom) break

        for(let i=top;i<=bottom;i++){
            matrix[i][right] = num
            num ++
        }
        right --
        if(left > right) break

        for(let i=right;i>=left;i--){
            matrix[bottom][i] = num
            num ++
        }
        bottom --
        if(top > bottom) break

        for(let i=bottom;i>=top;i--){
            matrix[i][left] = num
            num ++
        }
        left ++
        if(left > right){
            break
        }
    }
    return matrix
    // console.log(matrix)
};

其他解法

分圈逐层填满矩阵:

将矩阵由外到内分成若干层,每一层由四个相同大小的左闭右开区间组成。

图片来自代码随想录

var generateMatrix = function(n) {
    let startX = 0
    let startY = 0
    let loop = Math.floor(n/2)
    let mid = Math.floor(n/2)
    let offset = 1
    let num = 1
    let res = new Array(n).fill().map(() => Array(n))


    while(loop--){
        let row = startX
        let col = startY

        for(; col < startY+n - offset;col++){
            res[row][col] = num++
        }

        for(; row < startX + n - offset ; row++){
            res[row][col] = num++
        }

        for(; col > startY ; col --){
            res[row][col] = num ++
        }

        for(; row > startX ; row --){
            res[row][col] = num ++
        }

        startY++
        startX++
        offset += 2
    }

    if( n%2 ==1){
        res[mid][mid] = num
    }

    return res
};