122.买卖股票的最佳时机||
题目:122. 买卖股票的最佳时机 II - 力扣(LeetCode)
思路:感觉就是找上升区间,定义两个指针,移动终点去找下一个值,一旦发现数值下降,就计算下降前一个数字与起点的差值,遇到下降区间,则更新起点位置
尝试(部分AC)
class Solution {
public int maxProfit(int[] prices) {
int start = 0;
int result = 0;
int gap = 0;
int end = 0;
int earn = 0;
for(int i = 1; i < prices.length; i++){
gap = prices[i] - prices[i-1];
if(gap < 0){
result += end -start;
start = prices[i];
}else{
if(start == 0) start = prices[i-1];
end = prices[i];
earn = end - start;
}
}
if(result < 0) return 0;
return result;
}
}
答案
// 贪心思路
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;
}
}
小结
- 我的尝试中,无法处理全是上升的情况,因为我是在gap < 0时才更新结果
- 我想的是找到上升区间,还是太复杂了,按照卡尔的题解,直接收集正利润就行,每天跟前一天做差,把所有正利润加起来就行
55.跳跃游戏
思路:根据第一个下标的数值,产生一个区间,找区间里面最大的数字,再以该数字为起点,找区间最大的数,不断缩小,直到从起点出发,利用起点的步数可以到达终点,那终止条件咋搞,终止条件设定为区间为1吧,或者是区间为0
尝试(想不出来)
class Solution {
public boolean canJump(int[] nums) {
int start = 0;
int end = nums[0];
int gap = nums[0];
for(int i = start +1; i < end; i++ ){
max = Math.max(nums[i],nums[i-1]);
if(i == end -1){
start = start +
}
}
}
}
答案
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;
}
}
小结
- 很接近答案的思路,找区间里的最大值,但是没有想到终止条件
- 遍历区间是数值覆盖范围,每次移动都是在覆盖范围内移动,所以每次更新移动范围需要加上i【coverRange = Math.max(coverRange,i + nums[i]);】
45.跳跃游戏||
思路:感觉只需要加一点条件就行,每次更新覆盖范围就计数,重要覆盖范围可到达终点,就更新最小值
尝试(部分AC)
class Solution {
public int jump(int[] nums) {
if(nums.length == 1) return 0;
int count = 0;
int coverRange = 0;
int min = Integer.MAX_VALUE;
for(int i = 0; i <= coverRange && i < nums.length ; i++){
if(i + nums[i] > coverRange){
coverRange = i + nums[i];
count++;
}
if(coverRange >= nums.length -1){
min = Math.min(min,count);
};
}
return min;
}
}
答案
class Solution {
public int jump(int[] nums) {
int result = 0;
int end = 0;
int temp = 0;
for(int i = 0; i <= end && end < nums.length -1; i++){
temp = Math.max(temp,i + nums[i]);
if(i == end){
end = temp;
result++;
}
}
return result;
}
}
小结
- 题目说明总是能够到达,那么只需要保证,只在指针超出覆盖范围时,才计数,这样就保证了每次都把覆盖范围用到了极致。相当于,先遍历当前覆盖范围,过程中找到下一最大覆盖范围,覆盖范围区间遍历结束后,结果加一,进入下一覆盖范围