买卖股票的最佳时机II
买卖策略: 把整个过程拆解为每一天, 遍历整个股票交易日价格列表, 所有上涨交易日都买卖(赚到所有利润), 所有下降交易日都不买卖(永不亏钱), 也就是只考虑利润差为正的日子
局部最优:收集每天的正利润,全局最优:求得最大利润
class Solution {
public int maxProfit(int[] prices) {
int res = 0;
for(int i = 1; i < prices.length; i++){
res += Math.max((prices[i] - prices[i - 1]), 0);
}
return res;
}
}
跳跃游戏I
换一个思路, 就是每次跳跃的最大范围是否可以覆盖到最后一个下标
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点
细节:
- 这里遍历是取cover, 每次移动只能在cover的范围内移动
- 同时遍历时≤cover, 因为它要到cover的最后一个边界
class Solution {
public boolean canJump(int[] nums) {
//定义cover来判定距离
int cover = 0;
//剪个枝
if(nums.length == 1){
return true;
}
for(int i = 0; i <= cover; i++){
//这里的i + nums[i]就是第i个数可以走的最大范围
cover = Math.max(cover, i + nums[i]);
//如果超过了数组的最后一个下标, 说明可以跳出去
if(cover >= nums.length - 1){
return true;
}
}
return false;
}
}
跳跃游戏II
需要统计两个元素: 当前这一步的最大距离, 和上一步的最大距离, 如果遍历到了上一步的最大距离, 就需要跳一步
细节: for遍历里面是nums.length - 1, 因为最后只有两种情况:
- 要么是end=i, 说明正好到了nums.length - 1的位置, 那么根据if就要steps++
- 要么是end≠i, 说明他的最大范围包括了最后一个数, 所有不需要steps++
class Solution {
public int jump(int[] nums) {
//目前的最大距离
int maxDis = 0;
//上次的最大距离
int end = 0;
int steps = 0;
//这里是num.length, 因为如果不等于end,就会自动steps++
for(int i = 0; i < nums.length - 1; i++){
//更新目前最大距离
maxDis = Math.max(nums[i] + i, maxDis);
if(end == i){
end = maxDis;
steps++;
}
}
return steps;
}
}