977.有序数组的平方
最开始的思路是,使用双指针法来从数组的两端向中间遍历,选出最大的数字。.append()
方法是在列表的末尾添加元素,而不是开头。因此,如果按照从大到小的顺序将元素添加到新列表中,那么在最后反转列表之前,新列表实际上是按照递减顺序排列的。代码细节上我调整了几次,其中比较关键的区间的问题,一个还是.append()函数的问题,我试图用new.append(nums[left]*nums[left],new.append(nums[right]*nums[right]))一次添加两个,但事实.append()
方法只接受一个参数,即要添加到列表末尾的元素。
还有一个就是while left<=right:的判断,什么时候结束,我最开始觉得是left<right就可以了,当left==right时,当数组中只剩下一个元素时,它的平方就是需要添加到新数组中的最后一个元素。如果 left < right
作为循环条件,那么当 left
和 right
相等时,循环会提前结束,导致最后一个元素的平方没有被添加到新数组中。
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# 先看到非递减数组
# 要返回一个新的数组又由平方组成,需要新数组重新满足非递减
# 说明可能会会出现[-4,-1,0,3,10]这种负数,要判断谁最大,就可以双指针
# 不过这样是每次指针选择最大值/是直接赋值还是排序感觉需要考虑
# 我准备.sort()
# 不过复杂度O(n)我就不知道怎么确认了
new=[]
left=0
right=len(nums)-1
while left<=right:
if nums[left]*nums[left]>nums[right]*nums[right]:
new.append(nums[left]*nums[left])
left+=1
elif nums[left]*nums[left]<=nums[right]*nums[right]:
new.append(nums[right]*nums[right])
right-=1
new.sort()
return new
ps.数组反转的方法2 return new[::-1]
后来发现可以设一个k=len(nums)-1, 用new[k]=xxx k-- 的方法更新,不用翻转了
209.长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 连续
子数组
[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
这题尴尬了,很快想到了双指针滑动,但是一直很纠结,想是先固定left,去寻找满足求和大于等于target的right,先确定一个窗口,然后去移动两个指针,问题就来了,怎么同时移动两个指针呢?我还在想写窗口的大小的+1和-1,但是这又涉及到和target的大小判断,要记录最小值。就是首先想先写个循环来找到合适的两个初始的符合条件的指针,后来觉得实在是太麻烦了。
我的错误:
## 错误代码
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 话说感觉可以双指针做,长度是right-left+1
left,right=0,0
length_min=len(nums) ### 错误1
total=0
while right<len(nums):
if total<target:
right+=1 ## 错误2
total+=nums[right]
elif total>=target:
if total-nums[left]>=target:
left+=1
length_min=min(length_min,right-left+1)
return length_min
错误1:length_min
初始化为len(nums)
可能不是最佳的选择,因为如果没有找到任何满足条件的子数组,返回len(nums)
可能会让人误解为整个数组就是满足条件的子数组。但是存在例如[1,2,3,1,2] target=10,这种,就不满足了。
参考改为:length_min = float('inf')
错误2:直接移动right,total还设置为0,直接省去了第一个nums[0]
错误3: if total-nums[left]>=target:
这个条件判断并不正确,这个条件实际上是在检查去掉左指针所指向的元素后,剩余的总和是否仍然大于等于target
正确的逻辑应该是:当total
达到或超过target
时,先尝试更新最小窗口大小,然后再检查是否可以移动左指针(即去掉左指针所指向的元素后,剩余的总和是否仍然大于等于target
)。如果可以移动左指针,则移动它并更新total
。
话说这一版本我不知道错哪里了
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 初始化左右指针和最小长度
left, right = 0, 0
length_min = float('Inf') # 初始化为正无穷大
total = 0
# 开始遍历数组
while right < len(nums):
# 将当前元素加入总和
total += nums[right]
# 这里的逻辑错误:在total小于target时,错误地增加了right和total
if total < target:
right += 1
# 当总和达到或超过target时
elif total >= target:
# 更新最小长度
length_min = min(length_min, right - left + 1)
# 尝试移动左指针
total -= nums[left]
left += 1
# 返回最小长度
return length_min
# 我忘了之前right移动找到的已经是连续的能刚好满足target的情况了,不存在left移动了,right可以保持的情况
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 初始化左右指针和最小长度
left, right = 0, 0
length_min = float('Inf') # 初始化为正无穷大
total = 0
# 开始遍历数组
while right < len(nums):
# 将当前元素加入总和
total += nums[right]
while total >= target:
# 更新最小长度
length_min = min(length_min, right - left + 1)
# 尝试移动左指针
total -= nums[left]
left += 1
right+=1 # 我忘了之前right移动找到的已经是连续的能刚好满足target的情况了,不存在left移动了,right可以保持的情况
# 返回最小长度
return length_min if length_min != float('inf') else 0 # 要检查是否存在呀!!!
59.螺旋矩阵II
不会初始化空白矩阵,记录下:
在 Python 中,zeros
函数不是内置的,它通常是 NumPy 库中的一个函数。
有导入 NumPy 库,那么 zeros
函数会报错。可以通过以下方式导入 NumPy 并使用 zeros
函数:
import numpy as np
res = np.zeros((n, n), dtype=int)
或者,如果不想使用 NumPy,可以简单地使用列表推导式来创建一个空的二维列表:
nums = [[0] * n for _ in range(n)]
最开始写成
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
## 螺旋矩阵啊,好难拆解的样子
left, right = 0, n - 1
top, bottom = 0, n - 1
count = 1
target=n*n
res=zeros(n,n)
while count <= target:
#从左到右填充,相当于缩小上边界
for j in range(left,right): ##
res[top][j] = count
count+=1
#缩小上边界
top+=1
# 从上向下填充,相当于缩小右边界
for i in range(top,bottom): ##
res[i][right] = count
count+=1
#缩小右边界
right-=1
#从右到左填充,相当于缩小下边界
for j in range(right-1,left):
res[bottom][j] = count
count+=1
#缩小下边界
bottom-=1
# 从下向上填充,相当于缩小左边界
for i in range(bottom,top-1):
res[i][left] = count
count+=1
#缩小左边界
left+=1
return res
感觉几点:一个left/right,top/bottom会碰撞
for i in range(bottom,top-1): range
函数接受三个参数:起始值、结束值和步长,倒序!
在Python中,range(start, stop, step)
函数生成一个序列,从start
开始,到stop
结束(但不包括stop
),并且步长为step
。当我们从右向左填充时,我们需要从right
列开始,到left
列结束(不包括left
列),因此步长应该是-1
。
为了确保包括left
列的前一列,我们需要将stop
参数设置为left-1
,因为如果设置为left
,由于range
函数不包括结束值,那么left
列将不会被填充。
同理,四个range边界都要修改,这样就依次填充边界。
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
## 螺旋矩阵啊,好难拆解的样子
left, right = 0, n-1
top, bottom = 0, n-1
count = 1
target=n*n
res= [[0]*n for _ in range(n)]
while count <= target and left<=right and top<=bottom:
#从左到右填充,相当于缩小上边界
for j in range(left,right+1):
res[top][j] = count
count+=1
#缩小上边界
top+=1
# 从上向下填充,相当于缩小右边界
for i in range(top,bottom+1):
res[i][right] = count
count+=1
#缩小右边界
right-=1
#从右到左填充,相当于缩小下边界
for j in range(right,left-1,-1):
res[bottom][j] = count
count+=1
#缩小下边界
bottom-=1
# 从下向上填充,相当于缩小左边界
for i in range(bottom,top-1,-1):
res[i][left] = count
count+=1
#缩小左边界
left+=1
return res