题目链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)
作者思考:
做本题前,要先搞清楚一点题目要求:你在任何时候最多只能持有一股股票。你也可以先购买,然后在同一天出售。
提炼题意:你只可以持有一只股票,当前的操作只有买股票或卖股票
我如何才能使利润最大?本题有一个很巧妙的思路,我们可以每天买当天股票,第二天卖出,再买入当天的股票,计算每天的利润。重复上述步骤,就可以将一个利润分解看。我们只在利润为正的天进行抛出。
完整代码:
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. 跳跃游戏 - 力扣(LeetCode)
作者思考:
刚开始看见本题,很懵,数组的元素表示对应位置可以跳的最大步数,那么到底该跳几步呢,有那么多值可以选?
其实我们可以用覆盖范围来思考本题。
只要数组的终点在覆盖范围内就是说明可以到达最后一个下标值。
局部最优解:每次最大跳跃步数(即取最大覆盖范围)
整体最优解:最后得到整体最大覆盖范围,看是否能到终点
class Solution {
public boolean canJump(int[] nums) {
int size = nums.length;
if (size == 1) {
return true;
}
int len = 0;
//i 要在覆盖长度len中遍历
for (int i = 0; i <= size-1; i++) {
len = Math.max(len, nums[i] + i);
if (len >= size-1) {
return true;
}
}
return false;
}
}
题目链接:45. 跳跃游戏 II - 力扣(LeetCode)
作者思考:
本题跳跃游戏II 和 跳跃游戏的区别在于,本题要是一定可以到达数组终点,要求我们输出最少的跳跃次数。
局部最优:当前可移动距离及可能多走,如果还没到终点,步数再加一个。
整体最优:一步尽可能多走。从而达到最小步数
思路虽然是这样的,但是在写代码的时候还不能真的能跳多远就跳多远,那样就不知道下一步最远能跳到哪里了。
所以真正解题的时候,要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!(关键!!)
所以需要统计两个覆盖范围,当前这一步的最大覆盖范围和下一最大覆盖
class Solution {
public int jump(int[] nums) {
int size = nums.length;
if (size == 1) {
return 0;
}
int curlen = 0;//当前覆盖范围
int nextlen = 0;//下一步覆盖范围
int result = 0;//步数
for (int i = 0; i < size; i++) {
nextlen = Math.max(nextlen, nums[i] + i);
//当前下标遍历到 当前数组的最大长度时并且没有走到数组的尽头
if (i == curlen && curlen != size -1) {
result++;
curlen = nextlen;
}
}
return result;
}
}