题目与题解
122.买卖股票的最佳时机II
题目链接:122.买卖股票的最佳时机II
代码随想录题解:122.买卖股票的最佳时机II
视频讲解:贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机II_哔哩哔哩_bilibili
解题思路:
这题之前做过,所以思路记住了,第一次估计比较难想。
把股票的趋势图画出来,会得到一个有起伏的折线,如果每次都能在波谷买进,波峰卖出,收益必然最大。这个过程又可以分解到每一天,只要第二天的收益比第一天多,就可以第一天买进第二天卖出,即使连涨几天,比如第一天买进,波峰在第四天,那么第一天买进第四天卖出,和第一天买,第二天卖,第二天买,第三天卖,第三天买,第四天卖的结果是一样的。 所以只要判断数组的后一个元素比前一个元素大,就可以把nums[i] - nums[i-1]加入profit。
class Solution {public int maxProfit(int[] prices) {if (prices.length < 2) return 0;int profit = 0;for (int i = 1; i < prices.length; i++) {int diff = prices[i] - prices[i-1];if (diff > 0) profit += diff;}return profit;}
}
看完代码随想录之后的想法
这题贪心思路就这一种,写法上可以用profit += Math.max(0, prices[i]-prices[i-1])替代遍历的内容。
遇到的困难
无
55. 跳跃游戏
题目链接:55. 跳跃游戏
代码随想录题解:55. 跳跃游戏
视频讲解:贪心算法,怎么跳跃不重要,关键在覆盖范围 | LeetCode:55.跳跃游戏_哔哩哔哩_bilibili
解题思路:
自己写越写越乱,贪心基本是想到就是想到,想不到再怎么修补也不对。
看完代码随想录之后的想法
很巧妙的方法,一边遍历一边更新可遍历的最大范围,直到遍历的最大范围达到数组上限,则为true。如果遍历结束后最大范围仍未达到数组上限,则为false。
class Solution {public boolean canJump(int[] nums) {if (nums.length == 1) return true;int cover = 0;for (int i = 0; i <= cover; i++) {cover = Math.max(i + nums[i], cover);if (cover >= nums.length - 1) return true;}return false;}
}
遇到的困难
想不到就是真的想不到。
45.跳跃游戏II
题目链接:45.跳跃游戏II
代码随想录题解:45.跳跃游戏II
视频讲解:贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏II_哔哩哔哩_bilibili
解题思路:
一开始试图找到每个元素对印的最大覆盖范围,从而计算步数,但是边界各种不对,还是得看答案。
看完代码随想录之后的想法
理解本题的关键在于:以最小的步数增加最大的覆盖范围,直到覆盖范围覆盖了终点,这个范围内最少步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。
还是计算每个元素的最大覆盖范围,但同时计算当前元素最大覆盖范围和跳跃后的下一个元素最大覆盖范围。如果i到达curDistance,说明已经完成一次跳跃,对应步数加一,此时当前最大覆盖范围更新为nextDistance,直到nextDistance覆盖到数组上限即可。
class Solution {public int jump(int[] nums) {if (nums.length == 1) return 0;int count = 0;int curDistance = 0;int nextDistance = 0;for (int i = 0; i < nums.length; i++) {nextDistance = Math.max(nextDistance, nums[i]+i);if (i == curDistance) {count++;curDistance = nextDistance;if (nextDistance >= nums.length - 1) break;}}return count;}
}
遇到的困难
真的难想。
今日收获
贪心的题目没有套路,没有统一的解决方法,只能看灵光一现能不能想到,以及能不能记住结果。太难了,实在是太难了。