977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 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.长度最小的子数组
给定一个含有
n
个正整数的数组和一个正整数target
,找出该数组中满足其和 ≥target
的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回0
。
思路
滑动窗口。
- 窗口就是 满足其和 ≥
target
的长度最小的 连续子数组。 - 窗口的起始位置如何移动:如果当前窗口的值大于
target
了,窗口就要向前移动了(也就是该缩小了)。 - 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是
for
循环里的索引。
代码
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
给定一个正整数 n,生成一个包含 1 到 n^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)
,除了必要的返回输出数组以外,空间复杂度是常数。