前言
- 贪心就是局部最优达到最终全局最优,就是不回头的意思,每一步选择最优的选择,最后到达终点的时候就是全局最优
总结
- 贪心的核心就是维护一个当前最优状态(最远距离 / 最小价格 / 最远边界等),在一次遍历中不断更新这个最优状态
121.买卖股票的最佳时机
关键信息一句话总结:
遍历数组维护历史最低购入价格,用当前价格减去最低购入价格不断更新最大利润
java
class Solution {
public int maxProfit(int[] prices) {
// 贪心在 购入最低价格 卖出最高价格 然后不断记录利润最大值
int buyIn = prices[0];
int profit = 0;
for(int i = 0; i < prices.length; i++) {
buyIn = Math.min(prices[i], buyIn);
profit = Math.max(prices[i] - buyIn, profit);
}
return profit;
}
}
- 反思:我没有明白怎么进行建模,我能想到低买高卖,但是怎么写出来就不知道
55.跳跃游戏
关键信息一句话总结:
贪心维护当前能够到达的最远位置,只要当前位置不超过该范围就持续扩展最远距离
- 分析:它很像BFS一层一层地寻找
java
class Solution {
public boolean canJump(int[] nums) {
int maxReach = 0;
for(int i = 0; i < nums.length; i++) {
if(i > maxReach) {
return false;
}
// 一层一层 寻找下一次能到的最远距离
maxReach = Math.max(nums[i] + i, maxReach);
}
return true;
}
}
- 反思:我没有想明白如何开始寻找最大步数,写法很混乱,没想清为什么是for循环,不用模拟题目这样跳
45.跳跃游戏II
关键信息一句话总结:
每次在当前跳跃范围内寻找下一步最远可达位置,遍历到当前边界时完成一次跳跃,并更新新的边界
java
class Solution {
public int jump(int[] nums) {
int jumps = 0;
int end = 0;
int maxReach = 0;
// 其实就是在跳跃的范围中选择一个跳最远的步数 maxReach
for(int i = 0; i < nums.length - 1; i++) {
maxReach = Math.max(maxReach, i + nums[i]);
if(i == end) {
jumps++;
end = maxReach;
}
}
return jumps;
}
}
- 反思:我没有想明白maxReach = Math.max(maxReach, i + nums[i]);的含义,这一句就是在寻找每一步跳跃的过程中下一次能够到达的最远位置
763.划分字母区间
关键信息一句话总结:
记录每个字符最后出现的位置,遍历字符串不断更新当前片段的最远边界,当遍历到边界时就可以切分一个片段
java
class Solution {
public List<Integer> partitionLabels(String s) {
int[] last = new int[26];
for(int i = 0; i < s.length(); i++) {
// 记录26个字母最后出现的位置
last[s.charAt(i) - 'a'] = i;
}
List<Integer> result = new ArrayList<>();
int start = 0;
int end = 0;
for(int i = 0; i < s.length(); i++) {
// 延申到最远位置 因为最远位置有可能包含 所以取大的!
end = Math.max(end, last[s.charAt(i) - 'a']);
// 切割
if(i == end) {
result.add(end - start + 1);
start = i + 1;
}
}
return result;
}
}
- 反思:我没有想到记录每个字母最后出现的位置这一步,我有思考到延申