买卖股票的最佳时机II
122. 买卖股票的最佳时机 II - 力扣(LeetCode)
本题将利润按天进行分解,如假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。那么在计算最终最多的利润时只是需要将正利润进行相加即可
class Solution {
public int maxProfit(int[] prices) {
int res=0;
for(int i=1;i<prices.length;i++){
int m=prices[i]-prices[i-1];
if(m>0){
res+=m;
}
}
return res;
}
}
跳跃游戏
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
局部最优推出全局最优,找不出反例,试试贪心!
如图:
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 1) {
return true;
}
boolean[] isUse = new boolean[nums.length];
isUse[0] = true;
for (int i = 0; i < nums.length; i++) {
int cont = i + 1;
for (int j = 0; j < nums[i]; j++) {
if (cont >= nums.length) {
break;
}
isUse[cont++] = true;
}
}
for (int i = 0; i < isUse.length; i++) {
if (!isUse[i]) {
return false;
}
}
return true;
}
}
跳跃游戏II
所以真正解题的时候,要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!
这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
// 版本一
class Solution {
public int jump(int[] nums) {
if (nums == null || nums.length == 0 || nums.length == 1) {
return 0;
}
//记录跳跃的次数
int count=0;
//当前的覆盖最大区域
int curDistance = 0;
//最大的覆盖区域
int maxDistance = 0;
for (int i = 0; i < nums.length; i++) {
//在可覆盖区域内更新最大的覆盖区域
maxDistance = Math.max(maxDistance,i+nums[i]);
//说明当前一步,再跳一步就到达了末尾
if (maxDistance>=nums.length-1){
count++;
break;
}
//走到当前覆盖的最大区域时,更新下一步可达的最大区域
if (i==curDistance){
curDistance = maxDistance;
count++;
}
}
return count;
}
}