贪心理论基础
贪心的本质就是,局部最优可以达到全局最优。将问题分解成小问题,小问题寻找最优解,结合一起就是全局最优解。
所以贪心算法的使用条件:
- 贪心选择性质:只有当局部最优选择始终可以导致全局最优解时,贪心算法才能保证得到最优解。
- 最优子结构:原问题的最优解包含子问题的最优解。
455.分发饼干
思路
小饼干先喂饱胃口小的小孩。全局最优就是喂饱尽可能多的小孩。
代码
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
count = 0
g.sort()
s.sort()
pointer = 0
for cookie in s:
if pointer == len(g):
break
if cookie >= g[pointer]:
pointer += 1
count += 1
return count
复杂度分析
- 时间复杂度:
O(nlogn)
, 排序 - 空间复杂度:
O(1)
376. 摆动序列
思路
只看局部峰值,从而达到最长摆动序列。
有三种情况:
情况一:上下坡中有平坡
情况二:数组首尾两端
情况三:单调坡中有平坡
我们使用prediff和curdiff来判断是否有摆动。
代码
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
prediff = 0
curdiff = 0
res = 1
for i in range(len(nums) - 1):
curdiff = nums[i+1] - nums[i]
if prediff * curdiff <= 0 and curdiff != 0:
res += 1
prediff = curdiff
return res
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)
53. 最大子序和
思路
遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。
代码
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
res = nums[0]
temp = 0
for n in nums:
if temp <= 0:
temp = 0
temp += n
res = max(res, temp)
return res
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)