算法训练营(day32)
算法训练营(day32)
贪心算法理论基础
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
举个例子,在规定次数内从一堆钞票里怎么拿面额最大的钞票,根据贪心算法的思想:每次拿最大的就好(够贪就行O(∩_∩)O)
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
总而言之,贪心算法的本质其实就是 找到局部最优解,再比较所有的局部最优,得到全局最优。
122. 买卖股票的最佳时机 II
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
给你一个整数数组 prices
,其中 prices[i]
表示某支股票第 i
天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
解题思路
解题过程:
思路一:贪心算法
- 局部最优:收集每天的正利润
- 全局最优:累加正利润及最大利润
思路二:动态规划
定义 0 为没有持有股票, 1 为持有股票
dp[i][0]
取两种情况的最大值- 没有持有股票的现金
- 把股票卖了,减去买股票的支出后所赚的钱
dp[i][1]
也取两种情况的最大值- 持有股票,剩下的钱
- 当天买股票,剩下的钱
详细代码
解法一:贪心
1 | class Solution { |
解法二:动态规划
1 | class Solution { |
55. 跳跃游戏
题目链接:https://leetcode.cn/problems/jump-game/
给定一个非负整数数组 nums
,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
解题思路
解题过程:
思路一:贪心
- 局部最优:当前下标指定的值 能跳到的 最远下标
- 全局最优:如果 最远下标 不小于
nums.length - 1
,则说明可以到达最后一个下标
思路二:动态规划
- 同上
详细代码
思路一:贪心
1 | class Solution { |
思路二:动态规划
1 | class Solution { |
45. 跳跃游戏 II
题目链接:https://leetcode.cn/problems/jump-game-ii/
给定一个长度为 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]
。
解题思路
解题过程:
思路一:贪心
- 定义一个
end
表示当前覆盖的最远距离下标,end
最多到 倒数第二个数组 - 如果
i
走到end
,则更新到 下一步的最远距离下标tmp
- 如果
end
走到了nums.length - 2
,则说明 再跳一次必能到达nums[i - 1]
,直接增加一次跳跃次数即可
思路二:贪心
- 最普遍的贪心写法
- 定义 当前能到达的最远距离 和 下一步能到达的最远距离
- 每当
i
走到 当前能到达的最远距离,就更新 下一步能到达的最远距离 - 直到 下一步能到达的最远距离 涵盖了
nums.length - 1
,说明再跳一次即可到达,结束循环
详细代码
解法一:贪心
1 | class Solution { |
解法二:贪心
1 | class Solution { |