977.有序数组的平方
有负数。暴力快排:先对每个元素平方 o(n),再快排o(nlogn)(先分区 o(n),再递归排序 递归深度 logn)
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
nums[i] *= nums[i]
nums.sort() # reverse=True 降序
return nums
特殊情况是负数平方会变大,最大值只会在两端之一,有两个来源的可能,所以用双指针。定义长为n列表,要[None]*n 列表推导式,每个元素是none,而不是 [ ]*n,这个是对空列表重复n次,最终还是空列表。或者 res = [float('inf')] * len(nums)
初始化 inf是正无穷大
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
l = 0
r = n - 1
i = n - 1 # ans下标
ans = [None]*n # 定义长为n的列表
while l <= r:
if nums[l]**2 < nums[r]**2:
ans[i] = nums[r]**2
r -= 1
else:
ans[i] = nums[l]**2
l += 1
i -= 1
return ans
时间复杂度 O(n)
空间复杂度 O(1)
209.长度最小的子数组
暴力 O(n**2)
关键:正数,求和时只加不减,窗口由外往里,**但是!!不是有序的所以每次缩一点,最后不一定是长度最小的数组!!**错,这样没有考虑到不同段不同长度区间里的和
区间求和。以右端点为循环,左端点先不动;当右端点移动到的区间和大于等于t时,记录区间长度,更新ans和左端点,可是左端点可能不止移动一次,所以左端点是while。这样以一次循环右端点,最小的成本(左端点移动的不多),得到每段符合条件的区间,比较得到最小值。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 两个条件: 和为7 长度最小
# 和为7作为第一目标进行遍历,找到之后计算长度,时间复杂度 n^2
# 正数、增加一个数总和只增不减,如果左端点是枚举,右端点不断增加直到和>=7 就是极限,此时对于左端点,找到最短长度 复杂度n;
# 更新时left+1
# 或者以长度遍历,不断计算和,以长度能更快找到结果
n = len(nums)
l, r, ans, sum = 0, 0, float('inf'), 0
for r in range(0,n):
sum += nums[r]
while(sum >= target):
ans = min(ans, r - l +1)
# 注意:更新sum
sum -= nums[l]
l += 1
return ans if ans != float(inf) else 0 # 注意!!!如果不存在,ans就会inf,此时应该返回 0
注意:更新sum.注意!!!如果不存在,ans就会inf,此时应该返回 0
时间复杂度 O(n)
空间复杂度 O(1)
59.螺旋矩阵II
重点,边界处理!循环不变量,比如左闭右开,只处理第一个节点,最后一个节点,作为下一段的开头处理,就不会重复啦。这里我们每次都填满,好更新遍历的边界
遍历的边界不断在变,分为l , r, u, d, 当上面一行遍历填充好[l,r],u就下移,以此类推,循环的条件是cnt <= n*n保证n是奇数时最后中间的一点也能填上。
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
l, r, u, d = 0, n - 1, 0, n - 1 # 注意是n-1
cnt = 1
# 初始化结果矩阵
res = [[0] * n for _ in range(n)]
# print(res)
while cnt <= n * n:
for i in range(l, r + 1):
res[u][i] = cnt
cnt += 1
u += 1
for i in range(u, d + 1):
res[i][r] = cnt # 注意:l r容易反
cnt += 1
r -= 1
for i in range(r, l - 1, -1):
res[d][i] = cnt
cnt += 1
d -= 1
for i in range(d, u - 1, -1):
res[i][l] = cnt # 注意此时行是i
cnt += 1
l += 1
return res
注意:l和r容易错,应该画图写;注意range默认步长1,如果要倒序,得手动改步长-1;注意:数组行,列,i的位置