所以代码 java
买卖股票的最佳时机 II LeetCode 122
题目链接:买卖股票的最佳时机 II LeetCode 122 - 中等
思路
总利润就可以算作是每天的利润相加,要是利润最大化则当利润为正数时保留,利润为负数时舍去
class Solution {
public int maxProfit(int[] prices) {
int profitDiff = 0;
int result = 0;
// 利润都是从第二天开始算到最后一天
for (int i = 1; i < prices.length; i++) {
// result += Math.max(prices[i] - prices[i-1], 0);
profitDiff = prices[i] - prices[i-1];
if (profitDiff > 0) result += profitDiff; // 正数的利润保留
else profitDiff = 0; // 负数的利润舍去,重新使利润差为0
}
return result;
}
}
总结
本题和昨天摆钟的题类似,我们贪婪的是保留正数,负数给舍去。
if里面的三行代码可以简化到一行,即result += Math.max(prices[i] - prices[i-1], 0);
跳跃游戏 LeetCode 55
题目链接:跳跃游戏 LeetCode 55 - 中等
思路
我们只需要判断每个元素的覆盖范围,能否把终点给覆盖,如果可以就能到最后,不用去看他是跳一步还是两步。
class Solution {
public boolean canJump(int[] nums) {
// 只有一个元素一定返回ture
if (nums.length == 1) return true;
// 初始的覆盖范围为0
int cover = 0;
// 覆盖范围每次都在变化,只取最大的覆盖范围
// i <= cover 这里需要取等是因为每个覆盖范围的元素我们都是可以取到的
for (int i = 0; i <= cover; i++) {
// i + nums[i] 表示第i个元素的最大覆盖范围
cover = Math.max(cover, i + nums[i]);
if (cover >= nums.length - 1) return true;
}
return false;
}
}
总结
本题比较巧妙,贪心贪的是每次的覆盖范围(或者是能跳的最大步数),我们只取最大的覆盖范围并在次进行更新,直到最后能覆盖最后一个元素。
跳跃游戏 II LeetCode
题目链接:跳跃游戏 II LeetCode - 中等
思路
每次尽量跳最大的步数,然后记录下最大步数中的覆盖范围,然后每次更新的时候就更新覆盖范围。
class Solution {
public int jump(int[] nums) {
if (nums.length == 1) return 0;
int result = 0;
// 当前的覆盖范围
int cur = 0;
// 当前覆盖范围中,下一个最大的覆盖范围
int next = 0;
for (int i = 0; i < nums.length; i++) {
// 在cur覆盖范围中取最大的
next = Math.max(next, i + nums[i]);
if (cur == i){
// 如果当前覆盖范围没有到末尾
if (cur != nums.length){
// 就需要改变覆盖范围,并走一步
cur = next;
result++;
// 当然覆盖范围大于等于了最后一个数就可以返回了
if (cur >= nums.length - 1){
break;
}
}else break;
}
}
return result;
}
}
总结
本题主要是要记录下每个覆盖范围里面最大的那一个,然后我们那这个最大的覆盖范围作为我们新的覆盖范围。
另外本题可以有另一个写法:
class Solution {
public int jump(int[] nums) {
if (nums.length == 1) return 0;
int result = 0;
// 当前的覆盖范围
int cur = 0;
// 当前覆盖范围中,下一个最大的覆盖范围
int next = 0;
// 每次在覆盖范围里搜索更大的区域
// cur < nums.length - 1 意味着我们如果到不了 倒数第二个 位置,就继续改变cur
// 当刚好到这个位置之后,我们只需要再走一步就到最后了
for (int i = 0; i < nums.length - 1; i++) {
// 在cur覆盖范围中取最大的覆盖范围,做为下一个覆盖范围
next = Math.max(next, i + nums[i]);
// 当覆盖范围(cur)已被搜索完,且并没有覆盖到最后,就增大覆盖范围
if (cur == i){
cur = next;
result++;
}
}
return result;
}
}