滑动数组
209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left = right = 0
sums = 0
res = float('inf')
while right < len(nums):
sums += nums[right]
while sums >= target:
res = min(res, right-left+1)
sums -= nums[left]
left += 1
right += 1
return res if res != float('inf') else 0
904. 水果成篮
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
left = right = 0
basket = dict()
res = 0
while right < len(fruits):
if fruits[right] in basket: basket[fruits[right]] += 1
else: basket[fruits[right]] = 1
while len(basket) > 2:
basket[fruits[left]] -= 1
if basket[fruits[left]] == 0:
del basket[fruits[left]]
left += 1
res = max(res, right-left+1)
right += 1
return res
76. 最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
class Solution:
def minWindow(self, s: str, t: str) -> str:
left = right = 0
res = ""
count = float('inf')
tLen = len(t)
tDict = dict()
for val in t:
if val in tDict: tDict[val] += 1
else: tDict[val] = 1
sDict = dict()
while right < len(s):
if s[right] in sDict: sDict[s[right]] += 1
else: sDict[s[right]] = 1
while right-left+1 >= tLen and self.check(sDict, tDict):
if right-left+1 < count:
count = right-left+1
res = s[left:right+1]
sDict[s[left]] -= 1
left += 1
right += 1
return res
def check(self, sDict, tDict):
for k, v in tDict.items():
if k not in sDict: return False
elif sDict[k] < tDict[k]: return False
else: pass
return True
双指针
977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
left, right = 0, len(nums)-1
# res = []
res = [0] * len(nums)
iters = len(nums)-1
while left <= right:
left_square = nums[left] * nums[left]
right_square = nums[right] * nums[right]
if left_square > right_square:
# res.insert(0, left_square)
res[iters] = left_square
left += 1
else:
# res.insert(0, right_square)
res[iters] = right_square
right -= 1
iters -= 1
return res
移除元素
27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
解法一:数组中元素的相对顺序已被改变
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
left, right = 0, len(nums)-1
while left <= right:
if nums[left] == val:
nums[left], nums[right] = nums[right], nums[left]
right -= 1
else:
left += 1
return right + 1
解法二:数组中元素的相对顺序不被改变
注意:这种方式虽然保证了数组中元素的相对顺序不被改变,但移动元素的次数远比解法一更多,所以耗时也会更多
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
left = right = 0
while right < len(nums):
if nums[right] != val:
nums[left] = nums[right]
left += 1
right += 1
return left