贪心思想
00 min
2024-4-24
贪心算法(又称贪婪算法,最优子结构)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

1. 分发饼干(455 简单)

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
💡
每人只发一块饼干,为了尽可能满足最多数量的孩子,从贪心的角度考虑,应该按照孩子的胃口从小到大的顺序依次满足每个孩子,且对于每个孩子,应该选择可以满足这个孩子的胃口且尺寸最小的饼干。
示例 1:
示例 2:
代码实现:

跳跃游戏(55 中等)

贪心 数组 动态规划
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
示例 1:
示例 2:
💡
解法:倒序遍历,核心在于如何跳过0,当前0始终跳不过则为False。用flag标记状态,默认为True,如果遍历到0就变False,并记录0下标,然后查看后面元素能否跳过标记0的下标位置。
代码实现:

跳跃游戏(45 中等)*

贪心 数组 动态规划
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
  • 0 <= j <= nums[i]
  • i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]
示例 1:
示例 2:
 
💡
三种思路:动态规划、动态规划+贪心、+贪心
代码实现:
💡
贪心: 1. 首先明确第i个位置下次跳的范围为:i+1, nums[i] +i 2. 几个变量:end当前能达到的最远;max_pos下次能跳到的最远位置;steps最少跳跃次数(最终输出) 3. 思路:一次遍历,看下nums[i] +i 和max_pos谁最大,然后传递给max_pos。当i==end时,用max_pos更新end
💡
动态规划: 1. 定义状态列表
dp = len(nums)*float(”inf”) ,dp[i]表示跳到下标i所需要的最小跳跃次数。
2. 状态转义方程:
对于当前位置 i,如果之前的位置 j(0≤j<i0 \le j < i0≤j<i) 能够跳到位置 i 需要满足:位置 j(0≤j<i0 \le j < i0≤j<i)加上位置 j 所能跳到的最远长度要大于等于 i,即 j + nums[j] >= i 。而跳到下标 i 所需要的最小跳跃次数则等于满足上述要求的位置 j 中最小跳跃次数加 1,即 dp[i] = min(dp[i], dp[j] + 1)
  1. 初始条件
    1. 初始状态下,跳到下标 0 需要的最小跳跃次数为 0,即 dp[0] = 0
 

打家劫舍(LCR 89 中等)

数组 动态规划
 
 

最长公共子序列(LCR 095 中等)

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
  • 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
notion image