Day2| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.有序数组的平方.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
思考
存在非负数,平方之后相当于是一个开口向上的抛物线,最小值在中间,通过左右两个指针以此比较两端的大小,逐渐逼近中间的最小值。
注意 python list的.sort和.reverse操作返回的不是改变后的list。list本身会改变。
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# 左右指针向中间靠拢
i = 0
j = len(nums) - 1
res = []
while i <= j :
if nums[i]**2 < nums[j]**2:
res.append(nums[j]**2)
j-=1
else:
res.append(nums[i]**2)
i+=1
res.reverse()
return res
209.长度最小的子数组
题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。 拓展题目可以先不做。
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.长度最小的子数组.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
思考
1个多月前刷过这道题,又快忘了,想了20分钟才有点思路。代码写起来容易出错,尤其是if和while嵌套,什么时候用if,什么时候用while容易错乱。
下面的写法之所以长度为j-i,是因为sum_num+=nums[j]放在了while里,满足条件退出时,j多加了1
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# i j 表示滑动窗口的左右边界
# 窗口内的数之和小于target时,j++,大于target时,i++
i = 0
j = 0
sum_num = 0
min_len = 10000000000
while j < len(nums):
while (sum_num < target and j < len(nums)):
sum_num+=nums[j]
j+=1
while (sum_num >= target and i <= j):
#print(i,j)
if j-i < min_len:
min_len = j-i
sum_num-=nums[i]
i+=1
#print(sum_num)
if min_len == 10000000000:
return 0
return min_len
这个是之前的写法。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
i = 0
j = 0
n = len(nums)
sum_num = 0
min_res = 10000000
while j < n:
sum_num+=nums[j]
if sum_num<target:
j+=1
else:
while sum_num >= target:
min_res = min(min_res,j-i+1)
sum_num = sum_num - nums[i]
i+=1
j+=1
if min_res == 10000000:
min_res = 0
return min_res
其中if sum_num<target的判断条件可以合并在下面的while里,精简后的代码如下
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
l = len(nums)
left = 0
right = 0
min_len = float('inf')
cur_sum = 0 #当前的累加值
while right < l:
cur_sum += nums[right]
while cur_sum >= s: # 当前累加值大于目标值
min_len = min(min_len, right - left + 1)
cur_sum -= nums[left]
left += 1
right += 1
return min_len if min_len != float('inf') else 0
59.螺旋矩阵II
题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.螺旋矩阵II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
思考
跟算法关系不大,但是很考验边界条件的控制。本题通过左闭右开区间定义进行实现。
注意 python二维数组的初始化。通过l和r来定义遍历区间。因为是左闭右开,所有控制条件是l<r。(l=r时,取不到值了),所以如果n为奇数,最后会遇到l=r,就是最中间的数,需要单独处理一下。
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0] * n for i in range(n)]
# 区间定义
l = 0
r = n-1
index = 1
while l < r:
#初始化起点
i = l
j = l
#->
while j < r:
matrix[i][j] = index
index+=1
j+=1
#↓
while i < r:
matrix[i][j] = index
index+=1
i+=1
#<-
while j > l:
matrix[i][j] = index
index+=1
j-=1
#↑
while i > l:
matrix[i][j] = index
index+=1
i-=1
# 下一圈
l+=1
r-=1
if n%2 == 1:
#中间的数
i = int(n/2)
matrix[i][i] = index
return matrix
浙公网安备 33010602011771号