1. 买卖股票的最佳时机 II
122. 买卖股票的最佳时机 II - 力扣(LeetCode)
6
class Solution {
public int maxProfit(int[] prices) {
int maxIncome = 0;
for (int i = 1; i < prices.length; i++) {
maxIncome += Math.max(prices[i] - prices[i - 1], 0);
}
return maxIncome;
}
}
从图中可以发现,其实我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间。
那么只收集正利润就是贪心所贪的地方!
局部最优:收集每天的正利润,全局最优:求得最大利润。
2. 跳跃游戏
当前在的位置加上当前位置上的数,就是它在这个位置上的最远能到的位置
在范围内找到下一个最远能跳的位置
class Solution {
public boolean canJump(int[] nums) {
if(nums.length == 1)
return true;
int fp = 0; // furthest Position
for(int i = 0; i <= fp; i++){
if(nums[i] + i > fp)
fp = nums[i] + i;
// fp = Math.max(fp, nums[i] + i);
if(fp >= nums.length - 1)
return true;
}
return false;
}
}
不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
这个范围内,别管是怎么跳的,反正一定可以跳过来。
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
3. 跳跃游戏 II
找这一跳范围内的下一个最远能跳到的位置
class Solution {
public int jump(int[] nums) {
if(nums.length == 1)
return 0;
int count = 0;
int fp = nums[0]; // furthest Position
int[] max = {0, 0}; // (最远距离,下标)
for(int i = 0; i <= fp; i++){
if(fp >= nums.length-1){
count++;
break;
}
if(nums[i] + i > max[0]){
max[0] = nums[i] + i;
max[1] = i;
}
if(i == fp){
fp = max[0];
i = max[1];
count++;
}
}
return count;
}
}
class Solution {
public int jump(int[] nums) {
if(nums.length == 1)
return 0;
int count = 0;
int fp = nums[0]; // 当前能到的最远的位置
int nfp = 0; // 范围内下个最远位置
for(int i = 0; i < nums.length; i++){
nfp = Math.max(nfp,i+nums[i]);
if(fp >= nums.length - 1){ //跳一次到终点
count++;
break;
}
if(i == fp){ //遍历到了当前的最远位置,跳一次,更新最远位置
fp = nfp;
count++;
}
}
return count;
}
}
- 时间复杂度: O(n)
- 空间复杂度: O(1)