977.有序数组的平方
1.暴力解法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
# nums[i] = pow(nums[i], 2)
nums[i] *= nums[i]
nums.sort()
return nums
因为前面可能会有负数,因此再计算完之后要对整个数字进行一次排序
运行效果意外挺好
2.双指针法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
ans = list(range(0, n)) # 建立一个与nums等长的新数组
for i in range(n):
nums[i] = pow(nums[i], 2) # 将数组中每个数都平方
left = 0 #左指针
right = n - 1 #右指针
k = len(ans) - 1 #新指针
while left <= right: #判断判断nums[left]和nums[right]的大小
if nums[left] <= nums[right]: #将大的数存到新数组里
ans[k] = nums[right]
right -= 1
else:
ans[k] = nums[left]
left += 1
k -= 1
return ans
利用双指针
1.先建立一个与数组等长的新数组。
2.然后将数组中的每个元素平方
3.设定左指针left,右指针right,新数组指针s
4.当left<=right时,一直循环:
判断nums[left]和nums[right]的大小,将大的存入新数组,然后对应的指针为left就+1,right-1,k-1
209.长度最小的子数组
滑动窗口(双指针)
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
left, right = 0, 0
sum = 0 #记录窗口的和
res = float("inf") #记录长度,初始值为无限大
while right < n:
sum += nums[right]
while sum >= target: #当窗口内的和>target,开始缩小窗口
res = min(res, right - left + 1)
sum -= nums[left]
left += 1
right += 1
if res >= n+1:
return 0
else:
return res
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
在本题中实现滑动窗口,主要确定如下三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
解题的关键在于 窗口的起始位置如何移动,如图所示:
59.螺旋矩阵II
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
#初始化矩阵
matrix = [[0] * n for _ in range(n)]
#定义初始值
num = 1
left, right, top, bottom = 0, n-1, 0, n-1
while left <= right and top <= bottom:
#从左到右
for i in range(left, right + 1): #左闭右开
matrix[top][i] = num
num += 1
#从上到下
for i in range(top+1, bottom+1):
matrix[i][right] = num
num += 1
#从右到左
for i in range(right-1, left-1, -1):
matrix[bottom][i] = num
num += 1
#从下到上
for i in range(bottom-1, top, -1):
matrix[i][left] = num
num += 1
#缩小边界
left += 1
top += 1
right -= 1
bottom -= 1
return matrix
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
nums = [[0] * n for _ in range(n)]
startx, starty = 0, 0 # 起始点
loop, mid = n // 2, n // 2 # 迭代次数、n为奇数时,矩阵的中心点
count = 1 # 计数
for offset in range(1, loop + 1) : # 每循环一层偏移量加1,偏移量从1开始
for i in range(starty, n - offset) : # 从左至右,左闭右开
nums[startx][i] = count
count += 1
for i in range(startx, n - offset) : # 从上至下
nums[i][n - offset] = count
count += 1
for i in range(n - offset, starty, -1) : # 从右至左
nums[n - offset][i] = count
count += 1
for i in range(n - offset, startx, -1) : # 从下至上
nums[i][starty] = count
count += 1
startx += 1 # 更新起始点
starty += 1
if n % 2 != 0 : # n为奇数时,填充中心点
nums[mid][mid] = count
return nums
以下是chatgpt的解释
offset
是一个循环偏移量,表示当前循环中需要跳过的边界长度。假设当前正在填充第k
圈,其中k
从1开始递增,n
为矩阵的行列数,那么第k
圈的四条边分别为:
- 上边界:第
k
行,从第k
列到第n-k
列。 - 右边界:第
n-k
列,从第k
行到第n-k
行。 - 下边界:第
n-k
行,从第n-k
列到第k
列。 - 左边界:第
k
列,从第n-k
行到第k+1
行。
在每一圈循环中,我们需要填充四条边的所有元素,这些元素的总个数为n-2*k
个,所以我们需要将循环偏移量offset
初始化为1,然后在每一圈循环结束后将其加1。最终,当offset
的值等于loop
时,循环结束,矩阵填充完毕。