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

目录

  • 977.有序数组的平方
        • 思路
        • 代码
        • 复杂度分析
  • 209.长度最小的子数组
        • 思路
        • 代码
        • 难点
        • 复杂度分析
  • 59.螺旋矩阵II
        • 思路
        • 代码
        • 复杂度分析

977.有序数组的平方

Leetcode

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

思路

双指针。

数组平方的最大值就在数组的两端,不是最左边就是最右边。所以我们可以用一左一右两个指针,来获取最大值,再放入到我们的结果集。

代码
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        l, r, i = 0, len(nums) - 1, len(nums) - 1
        res = [0] * len(nums)

        while l <= r:
            if nums[l] ** 2 < nums[r] ** 2:
                res[i] = nums[r] ** 2
                r -= 1
            else:
                res[i] = nums[l] ** 2
                l += 1
            i -= 1
        return res
复杂度分析
  • 时间复杂度:O(n)
  • 空间复杂度:O(1), 除了存储答案的数组以外,我们只需要维护常量空间。

209.长度最小的子数组

Leetcode

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

思路


滑动窗口。

  • 窗口就是 满足其和 ≥ target 的长度最小的 连续子数组。
  • 窗口的起始位置如何移动:如果当前窗口的值大于target了,窗口就要向前移动了(也就是该缩小了)。
  • 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

代码随想录算法训练营第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第1张图片

代码
class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        j = 0
        total = 0
        minLen = len(nums)
        # edge case
        if sum(nums) < target:
            return 0

        for i in range(len(nums)):
            total += nums[i]
            while total >= target:
                minLen = min(minLen, i - j + 1)
                total -= nums[j]
                j += 1

        return minLen
难点

我在写码的时候,j += 1 写在了 total -= nums[j]的前面,导致更新total的时候会删掉不是最左侧的元素。需要注意代码的顺序。

复杂度分析
  • 时间复杂度:O(n), 每个元素最多被操作两次,所以时间复杂度是 2 × n 也就是O(n)
  • 空间复杂度:O(1)

59.螺旋矩阵II

Leetcode

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

思路

矩阵填充顺序如下:

代码随想录算法训练营第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II_第2张图片

具体遵循的规则是左开右闭,每次遇到的拐角留给下条边来处理。

代码
class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        res = [[0] * n for _ in range(n)]
        startx, starty = 0, 0
        loop, mid = n // 2, n // 2
        count = 1
        
        for offset in range(1, loop + 1):
            #upper left to right
            for i in range(starty, n - offset):
                res[startx][i] = count
                count += 1
            
            #up to bottom
            for i in range(startx, n - offset):
                res[i][n - offset] = count
                count += 1

            # from bottom right to left
            for i in range(n - offset, starty, -1):
                res[n - offset][i] = count
                count += 1
            
            # from bottom to up
            for i in range(n - offset, startx, -1):
                res[i][starty] = count
                count += 1
            
            startx += 1
            starty += 1
        
        if n % 2 != 0:
            res[mid][mid] = count

        return res
复杂度分析
  • 时间复杂度:O(n^2),因为遍历了一遍n*n矩阵。
  • 空间复杂度: O(1),除了必要的返回输出数组以外,空间复杂度是常数。

你可能感兴趣的:(代码随想录算法训练营,算法,矩阵,线性代数,leetcode,python)