455.分发饼干
大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子。
局部最优:尽量确保每块饼干被充分利用
全局最优:手上的饼干可以满足尽可能多的孩子
思路:大饼干 尽量分给 大胃口孩子
将小孩和饼干数组排序,我们从大到小遍历小孩。对于胃口最大的小孩,我们查看最大的饼干能否满足,如果不能,则说明此小孩无法被满足,无需查看其他更小的饼干,直接判断胃口稍微小一点的小孩。
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort()
s.sort()
count = 0
# 定位到最大的饼干
cookie_index = len(s) - 1
# 遍历小孩
for child_index in range(len(g) - 1, -1, -1):
# 确保最大的饼干优先给胃口最大的小孩
if cookie_index >= 0 and s[cookie_index] >= g[child_index]:
count += 1
cookie_index -= 1
return count
376.摆动序列
由于本题让我们求最长摆动子序列的 长度,因此只需要 记录,而不需要 删减。
在处理摆动序列问题时,主要会遇到以下几种情况:
摆动
连续上升
连续下降
平坡
只有 上升后下降 或者下降后上升,才能被记一次摆动,因此我们需要创建两个变量来记录 当前子序列最后一次的状态。
up
变量:表示如果序列在当前点结束并且最后一次摆动是上升的,那么摆动序列的最长长度是多少。每当我们发现一个元素比前一个元素大,就意味着我们可以在之前的下降摆动序列的基础上增加一个上升摆动,因此up
的值会更新为down + 1
。
down
变量:表示如果序列在当前点结束并且最后一次摆动是下降的,那么摆动序列的最长长度是多少。每当我们发现一个元素比前一个元素小,就意味着我们可以在之前的上升摆动序列的基础上增加一个下降摆动,因此down
的值会更新为up + 1
。有了这两个变量,我们就不需要关心两个摆动之间的任何非摆动状态,因为前一个摆动的状态已经被两个变量记录。
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
n = len(nums)
# 单个元素本身就是摆动序列,因此初始化最小摆动序列长度为 1
if n < 2:
return 1
up = down = 1
# 从第二个元素开始遍历
for i in range(1, n):
if nums[i] > nums[i-1]:
up = down + 1
elif nums[i] < nums[i-1]:
down = up + 1
return max(up, down)
53.最大子数组和
注意本题要求 连续子数组。有以下观察:
- 当连续和为负数时,与后一个数相加,只会令其变得更小,应重新开始计算子数组和。
- 当连续和为正数时,与后一个数相加,只会令其变得更大,应继续累加。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_sum = float('-inf')
cur_sum = 0
for num in nums:
cur_sum += num
# 维护最大子数组和
if cur_sum > max_sum:
max_sum = cur_sum
# 如果子数组和为负,重新计算子数组和
if cur_sum < 0:
cur_sum = 0
return max_sum