977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
解决方法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
res=[0]*len(nums)
#双指针往中间逼近
low=0
high=len(nums)-1
for i in range(len(nums)):
loc=len(nums)-i-1
if nums[low]**2>nums[high]**2:
res[loc]=nums[low]**2
low+=1
else:
res[loc]=nums[high]**2
high-=1
return res
209.长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 子数组
[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
解决方法
自己开始写的一个有一个用例超时了
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
res=[]
flag=0
for i in range(len(nums)):
res.append(nums[i])
if sum(res)>=target:
flag=1
break
if flag==0:
return 0
minx=len(res)
#双指针
low=0
high=len(res)-1
while high<=len(nums)-1:
while sum(res)>=target:
a=res.pop(0)
low+=1
res.insert(0,a)
low-=1
if len(res)<minx:
minx=len(res)
if high!=len(nums)-1:
high+=1
res.append(nums[high])
else:
break
return minx
想法倒是没啥问题,但是问题在于首先初始化目标列表时的逻辑其实跟后续修正列表的逻辑是一样的(一个个添元素,大于了就从前面开始删),因此没必要把初始化目标列表和后续修正分开写,其次就是没必要用个额外列表存储,这样子时间复杂度有点高了(应该主要是insert,pop表头)
然而这样也超时。。。。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
low=high=0
sumx=0
flag=0
minx=len(nums)
while high<=len(nums)-1:
while sum(nums[low:high+1])>=target:
if high-low+1<minx:
minx=high-low+1
flag=1
low+=1
high+=1
if flag==0:
return 0
return minx
原来还有sum求和导致时间复杂度高的原因,这里用sum每一次循环都要从头到尾再求一次和,可是他的和其实一次循环只会变化一个数,所以我们用total来存储,最后如下
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
low=high=0
sumx=0
flag=0
minx=len(nums)
total=0
while high<=len(nums)-1:
total+=nums[high]
while total>=target:
if high-low+1<minx:
minx=high-low+1
flag=1
total-=nums[low]
low+=1
high+=1
if flag==0:
return 0
return minx
59.螺旋矩阵II
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
解决方法
左闭右开
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
li=[[0 for i in range(n)] for i in range(n)]
x=0
y=0
count=1
quan=1
for quan in range(1,n//2+1):
while y<n-quan:
li[x][y]=count
y+=1
count+=1
while x<n-quan:
li[x][y]=count
x+=1
count+=1
while y>quan-1:
li[x][y]=count
y-=1
count+=1
while x>quan-1:
li[x][y]=count
x-=1
count+=1
x+=1
y+=1
if n%2==1:
li[n//2][n//2]=n**2
return li
滑动窗口补充题
904.水果成篮
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits
表示,其中 fruits[i]
是第 i
棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
- 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
- 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
- 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits
,返回你可以收集的水果的 最大 数目。
解决方法
之前那个滑动窗口是使窗口尽可能小,这个是使窗口尽可能大,然后就没啥差别了。
(当题目注重于一个子数组的长度时,考虑用滑动窗口?)
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
low=high=0
maxx=0
while low<=high:
while len(set(fruits[low:high+1]))<=2 and high<=len(fruits)-1:
if high-low+1>maxx:
maxx=high-low+1
high+=1
low+=1
return maxx
上述方法又超时了/(ㄒoㄒ)/~~,明天再改吧
改
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
# 初始化
i, j = 0, 0
res = 0
classMap = defaultdict(int)
classCnt = 0
# 移动滑窗右边界
while j < len(fruits):
# 判断当前是否满足条件
if classMap[fruits[j]] == 0:
classCnt += 1
classMap[fruits[j]] += 1
# 若不满足条件,移动i
while classCnt > 2:
if classMap[fruits[i]] == 1:
classCnt -= 1
classMap[fruits[i]] -= 1
i += 1
# 一旦满足条件,更新结果
res = max(res, j - i + 1)
j += 1
return res
作者:HelloPGJC
链接:https://leetcode.cn/problems/fruit-into-baskets/solutions/1437444/shen-du-jie-xi-zhe-dao-ti-he-by-linzeyin-6crr/
来源:力扣(LeetCode)