贪心算法
什么是贪心算法?
就是每一阶段的最优解,从局部的最优解达到全局的最优解!
最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧。
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
455. 分发饼干
思路:这类涉及列表的数据!可以先考虑对列表进行排序先!然后优先满足最小胃口的或者排序优先满足最大胃口的都可以!
局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
class Solution:def findContentChildren(self, g: List[int], s: List[int]) -> int:s.sort()g.sort()count = 0sum = 0for _g in g:while sum < len(s):if _g <= s[sum]:count += 1s[sum] = -1breaksum += 1return countclass Solution:def findContentChildren(self, g, s):g.sort() # 将孩子的贪心因子排序s.sort() # 将饼干的尺寸排序index = 0for i in range(len(s)): # 遍历饼干if index < len(g) and g[index] <= s[i]: # 如果当前孩子的贪心因子小于等于当前饼干尺寸index += 1 # 满足一个孩子,指向下一个孩子return index # 返回满足的孩子数目
376. 摆动序列
思路:理解题目,一上一下就是产生峰值就是摆动了!这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点
class Solution:def wiggleMaxLength(self, nums: List[int]) -> int: if len(nums) <= 1:return len(nums)pre_diff = 0 #前一对元素的差值 cur_diff = 0 #当前一对元素的差值count = 1 # 记录峰值for i in range(len(nums) - 1):cur_diff = nums[i + 1] -nums[i]if (pre_diff >= 0 and cur_diff < 0) or (pre_diff <= 0 and cur_diff > 0):count += 1pre_diff = cur_diffreturn count
53. 最大子数组和
思路:关键点是,每次的比较叠加的和不能小于0,否则不如当前的数大了!还有使用额外列表来做的思想也很精妙!关键点也是大于0这一点!
class Solution:def maxSubArray(self, nums: List[int]) -> int:# 使用额外列表来解决dp = [0] * len(nums)dp[0] = nums[0]for i in range(1, len(nums)):if dp[i - 1] > 0: dp[i] = dp[i - 1] + nums[i]else:dp[i] = nums[i]return max(dp)def maxSubArray1(self, nums: List[int]) -> int:# 使用滑动窗口来解决 关键点就是每次比较的和知否大于当前的数值cur = nums[0]temp = 0for _num in nums:temp += _num# 如果临时值大于当前窗口的最大值 重新赋值if temp > cur:cur = temp# 如果不小于0的哇,怎么累加都不会小于刚加的那个值了!if temp < 0:temp = 0return cur