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

题目简介

977 https://leetcode.cn/problems/squares-of-a-sorted-array/description/
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

209 https://leetcode.cn/problems/minimum-size-subarray-sum/description/
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

59 https://leetcode.cn/problems/spiral-matrix-ii/description/
给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

初见思路

977: 数组中每个元素求平方,然后重排序,排序算法用归并可以到O(nlogn) ,空间占用O(1), 但是一定不是最佳;考虑用一个返回数组,从右到左存放由大到小的平方数,时间O(N)空间O(N); 顺利AC。

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        ans = [0] * len(nums)
        l, r, idx = 0, len(nums) - 1, len(nums) - 1
        while l <= r:
            if nums[l] ** 2 > nums[r] ** 2:
                ans[idx] = nums[l] ** 2
                l += 1
            else:
                ans[idx] = nums[r] ** 2
                r -= 1
            idx -= 1
        return ans

209: 注意这题只要返回最短子数组的长度,想滑动窗口,这里使用两个指针,左指针固定,右指针遍历累加,当累加和大于等于目标值时,记录子数组长度。最后返会所有子数组中最小的。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        l,r = 0,0
        sub_sum = 0
        min_len = float('inf')
        while r < len(nums):
            sub_sum += nums[r]
            
            while sub_sum >= target:
                min_len = min(min_len, r - l + 1)
                sub_sum -= nums[l]
                l += 1
            r += 1
        
        return min_len if min_len != float('inf') else 0

写的时候还是有些问题,记住本题滑动窗口像一个容量有限的口袋(看情况,滑动窗口可以根据题目扩容、定容、缩容),和大于目标的时候去掉最左侧元素,才能发现更多符合条件的窗口。还有就是记得Python中无限大数的写法。

59: 对于这类以奇怪方式遍历数组的题目,在没有好的方式遍历的情况下,就直接想办法模拟

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = list(range(1,n**2+1))
        ans =  [[0 for _ in range(n)] for _ in range(n)]
        
        idx = 0
        l,r,t,b = 0,n-1,0,n-1
        i,j = 0,0
        while idx < n**2:
            # l -> r
            for j in range(l,r+1):
                ans[i][j] = nums[idx]
                idx += 1
            t += 1

            # t -> b
            for i in range(t,b+1):
                ans[i][j] = nums[idx]
                idx += 1
            r -= 1

            # r -> l
            for j in range(r,l - 1,-1):
                ans[i][j] = nums[idx]
                idx += 1
            b -= 1

            # b -> t
            for i in range(b,t - 1,-1):
                ans[i][j] = nums[idx]
                idx += 1
            l += 1
        
        return ans

模拟的逻辑不算很顺畅,究其原因是刚上手没有拿捏到边界收缩的规律:右上收缩t, 右下收缩r,左下收缩l,左上收缩l;

复盘思路

https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html

重点难点

见复盘思路

今日收获

  1. 数组遍历技巧
  2. 滑动窗口
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容