122.买卖股票的最佳时机II
局部最优:收集每天的正利润,全局最优:求得最大利润。
本题首先要清楚两点:
- 只有一只股票!
- 当前只有买股票或者卖股票的操作
想获得利润至少要两天为一个交易单元
贪心算法
如果想到其实最终利润是可以分解的,那么本题就很容易了!
如何分解呢?
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!
class Solution {
public int maxProfit(int[] prices) {
int result = 0;
for (int i = 1; i < prices.length; i++) {
result += Math.max(prices[i]-prices[i-1],0);
}
return result;
}
}
55. 跳跃游戏
跳几步无所谓,关键在于可跳的覆盖范围!问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
贪心算法
局部最优解:每次取最大跳跃步数(取最大覆盖范围),
整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
注意
每次取下标加上数组对应的值可以得出此时的覆盖范围。
class Solution {
public boolean canJump(int[] nums) {
if(nums.length == 1)return true;
int cover = 0;
for (int i = 0; i <= cover; i++) {
cover = Math.max(cover,nums[i]+i);
if(cover >= nums.length -1)return true;
}
return false;
}
}
45.跳跃游戏II
(以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点)
贪心的思路,
局部最优:当前可移动距离尽可能多走,如果还没到终点,步数再加一。
整体最优:一步尽可能多走,从而达到最少步数。
从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!
这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。
class Solution {
public int jump(int[] nums) {
if(nums == null ||nums.length == 1 || nums.length == 0 )return 0;
int count=0;
int cur = 0,next =0;
for (int i = 0; i < nums.length; i++) {
next = Math.max(i+nums[i],next);
if(i == cur){
if(cur != nums.length-1){
count++;
cur = next;
if(cur >= nums.length-1) break;
}else break;
}
}
return count;
}
}
补充:
nums == null
检查引用是否为空,即数组是否被正确初始化。nums.length == 0
检查数组本身的长度是否为 0,即数组是否存在但是没有元素