977 有序数组的平方
代码:
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
l, r, i = 0, n-1, n-1
res = [0] * n
while l <= r:
if nums[l] ** 2 > nums[r] ** 2:
res[i] = nums[l] ** 2
l += 1
else:
res[i] = nums[r] ** 2
r -= 1
i -= 1
return res
解题思路: 一个非递减顺序的数组,可得平方最大值不是在最左边就是在最右边,所以最左边和最右边比,哪个大就写入新数组的最右边。
209 长度最小的子数组
代码:
import math
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left, right = 0, 0
windows_sum = 0
res= float("inf")
while right < len(nums):
windows_sum += nums[right]
right += 1
while windows_sum >= target:
res = min(res, right - left)
windows_sum -= nums[left]
left += 1
return 0 if res == float("inf") else res
解题思路: 这道题的关键在于使用滑动窗口算法。滑动窗口算法就是动态调整窗口的起始位置,先移动结束位置,直到窗口内满足条件,然后再移动起始位置,直到窗口内不满足条件,一直到快指针遍历完数组。个人理解,窗口就像个毛毛虫,先动头,再动尾,一直到头到达终点。以这道题为例,要找满足其和>=s的长度最小的连续子数组,就意味着,先移动快指针,直到窗口内的数组满足条件,然后再移动慢指针,直到窗口内的数之和不满足条件,这个时候要注意更新找到子数组的最小长度。然后快指针再动,慢指针再动,直到终点。
难点:
个人认为滑动窗口最难理解的就是这个窗口是个动态的,先要明确窗口里是什么,这道题窗口就是nums[left,right],然后要明确窗口滑动的条件是什么,windows_num > target,然后要注意窗口要扩大和收缩,这个过程中窗口要更新数据。
还要注意滑动窗口算法的时间复杂度是O(N),因为每个元素都进入和离开窗口一次,时间复杂度是2N。
59 螺旋矩阵||
**题目: leetcode.cn/problems/sp…
代码:
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0 for _ in range(n)] for _ in range(n)]
upper_bound, lower_bound = 0, n - 1
left_bound, right_bound = 0, n - 1
num = 1
while num <= n * n:
# 在顶部从左往右走
for j in range(left_bound, right_bound+1, 1):
matrix[upper_bound][j] = num
num += 1
upper_bound += 1 # 上边界向下缩
# 在右边从上往下走
for i in range(upper_bound, lower_bound+1, 1):
matrix[i][right_bound] = num
num += 1
right_bound -= 1 # 右边界向左缩
# 在下边从右往左走
for j in range(right_bound, left_bound-1, -1):
matrix[lower_bound][j] = num
num += 1
lower_bound -= 1 # 下边界向上缩
for i in range(lower_bound, upper_bound-1, -1):
matrix[i][left_bound] = num
num += 1
left_bound += 1
return matrix
解题思路: 顺时针螺旋,就是一圈一圈往里走,每一圈分四步:在顶部从左往右走,在右边从上往下走,在下边从右往左走,在左边从下往上走,循环的边界条件写对就行。
难点:
要注意每走一步,对应的边界都要向里缩,比如走完“在顶部从左往右走”,上边界就要往里缩;然后就是注意每步写for循环的边界值,比如“在顶部从左往右走”,是range(left_bound, right_bound+1)而不是range(left_bound, right_bound),因为range是[left_bound, right_bound+1)。
今日感悟
连做题带写题解,大概用了两个半小时,主要是费在理解滑动窗口算法还是调试螺旋矩阵的边界值。感觉做题还是要把问题分解为小问题,然后再解决小问题,直到问题解决,想的过程中脑子要清醒,把步骤写下来再写代码。