122.买卖股票的最佳时机||
文章链接:代码随想录 (programmercarl.com)
思路:
(1)根据题目的要求,题目最多只能持有一股股票,其实买股票和卖股票可以拆分为几天的过程
(2)举例,比如有数组【5,1,3,2,8】,可以明显的发现最大利润应该是第二天买入,然后第五天卖出,此时的利润为7,将这个买卖过程拆分为几天,即-1 + 3 - 3 + 2 - 2 + 8 = 7,详细过程为:第二天以1的价格买入,第三天以3卖出,第三天买入3,第四天以2卖出,再在第四天以2买入,最后在第五天以8的价格卖出
(3)然后发现-1 + 3 - 3 + 2 - 2 + 8 其实就是 2 + (-1)+ 6 = 7,即相邻两天的数字之差(贪心:局部最优),然后累加
(4)因为要进行累加,所以需要设计初始result的值,注意此时result的值应该设置为0,因为如果利润为负数,就不需要累加了
Java代码:
class Solution {
public int maxProfit(int[] prices) {
int result = 0;//初始要设为0
//判断特殊情况
if(prices.length == 1){
return result;
}
for(int i = 1; i < prices.length;i++){
if((prices[i] - prices[i - 1]) > 0){
result += prices[i] - prices[i - 1];
}
}
return result;
}
}
55.跳跃游戏
文章链接:代码随想录 (programmercarl.com)
思路:
(1)本质上是看每个元素的覆盖范围,看覆盖范围是否能够到达数组末
(2)覆盖范围应该为当前位置元素值 + 1
看完文章后的反思:
(1)其实跳几步无所谓,关键在于可跳的覆盖范围!
(2)贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点
(3)i每次移动只能在cover的范围内移动,每移动一个元素,cover得到该元素数值(新的覆盖范围)的补充,让i继续移动下去
(4)而cover每次只取 max(该元素数值补充后的范围, cover本身范围),如果cover大于等于了终点下标,直接return true就可以了
Java代码:
class Solution {
public boolean canJump(int[] nums) {
//判断特殊情况
if(nums.length == 1){
return true;
}
//初始化覆盖范围
int coverrange = 0;
for(int i = 0 ; i <= coverrange;i++){
coverrange = Math.max(coverrange,i + nums[i]);
if(coverrange >= nums.length - 1){
return true;
}
}
return false;
}
}
45.跳跃游戏||
文章链接:代码随想录 (programmercarl.com)
思路:跟跳跃游戏思路部分一致,还是看最大覆盖长度,后面就没思路了
看完文章后的反思:
45. 跳跃游戏 II - 力扣(Leetcode)该篇文章的思路很清楚,且有很多代码细节
Java代码:
(细节:i < nums.length - 1,因为该代码是进入循环的一开始就起跳,如果 i 跳到了数组末,那么还会进入循环,然后跳跃的步数就加1了)
(for循环条件也可以写成如下这样)
i <= end && end < nums.length - 1
class Solution {
public int jump(int[] nums) {
//先判断特殊情况
if(nums == null || nums.length == 0 || nums.length == 1){
return 0;
}
int step = 0;
int maxrange = 0;
int end = 0;//end表示最大覆盖范围的边界
for(int i = 0; i < nums.length - 1;i++){
maxrange = Math.max(maxrange,i + nums[i]);
if(i == end){
end = maxrange;
step++;
}
}
return step;
}
}