代码随想录训练营Day 35|力扣122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II

1.买卖股票的最佳时机2

代码:(贪心算法)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int sum = 0;
        for(int i = 0;i < prices.size() - 1;i++){
            sum += max(prices[i + 1] - prices[i],0);
        }
        return sum;
    }
};

 思路:题意是,我们可以多次买入股票(在不同的天数),然后让我们求最大利润。

        这里的局部最优是:每次都收获正利润;全局最优是:找到最大的利润总和

        具体的做法就是:我们可以把 前一天买的股票在今天卖出去获得正利润 的所有利润相加

那为什么可以这么做?你这样不是忽略了我可以隔着好几天再卖股票的情况了吗?

         举个例子:假设你第三天买入股票,第六天卖出。那你的总利润就是prices[6] - prices[3]。

        其实这个式子的值等价于 (prices[6] - prices[5] )+ (prices[5] - prices[4] ) + (prices[4] - prices[3] ),即我从第三天开始买入股票,接下来每一天,我都卖出前一天的股票,然后买入今天的股票。这正是我的代码里体现的情况。

2.跳跃游戏 

 代码:(贪心算法)

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0;
        if(nums.size() == 1) return true;
        for(int i = 0;i <= cover;i++){
            cover = max(cover,i + nums[i]);
            if(cover >= nums.size() - 1){
                return true;
            }
        }
        return false;
    }
};

思路: 

这道题涉及到很多选择,感觉很麻烦,是不是有很多种情况,这怎么搞?

如果这样想的话,那确实很复杂。但题上只要求我们给出能不能覆盖,也没有问我们怎么覆盖。那我们就可以直接去看“覆盖范围”能否把整个数组长度覆盖就可以了。

这里的局部最优就是:找当前最大的覆盖范围;全局最优:成功覆盖整个数组。

覆盖范围是什么,怎么表示?

覆盖范围就是当前,你所能跳跃的最大范围。我们可以借助一个例子来思考怎么表示——假设你跳到了第3个元素,然后此元素值为5,那就就最远可以跳到3+nums[3]。所以cover为max(cover,i + nums[i])

那你要怎么判断覆盖范围是否超过数组长度了呢?以及你的cover都比数组长度长了的话,你是不是会导致数组越界?

我采用,在每一次循环里,都进行一次if判断,这样如果cover已经可以覆盖数组的话,就直接返回了,不会继续进行循环,也就不会越界访问了;如果没有覆盖数组,那说明cover此时比数组最后的下标要小,更不会越界了。

注意:这里的cover覆盖范围,是从0开始的。所以比较的时候,是和nums.size() - 1 比。

3.跳跃游戏2

代码: 

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int result = 0; // 最少跳几步
        int cur = 0; // 当前的覆盖范围
        int next = 0; // 下一步的覆盖范围
        for(int i = 0;i <= cur;i++){
            next = max(next,i + nums[i]);
            if(i == cur){
                result++;
                cur = next;
                if(cur >= nums.size() - 1){
                    break;
                }
            }
        }
        return result;
    }
};

 思路:

 这道题涉及到了求最少的步数,上一道题只涉及到了判断能否覆盖。

这道题要怎么贪?  

局部最优为:用最少的步数,找每一次最大的覆盖范围。全局最优为:最少的步数跳完整个数组 

那我们怎么选择下一次最大的覆盖范围? 

遍历当前的覆盖范围,用next变量来收集当前这一步中,下一次可以涉及的最大覆盖范围。 

找到了最大覆盖范围,就要跳到对应的最远的地方吗?

不是的,是在这一步的覆盖范围内,找下一次最大的覆盖范围。

也就是,不关注具体要跳到哪里,而是关注最远的覆盖范围。 

你要怎么统计步数?进行“跳跃”?

在当前的覆盖范围已经用完,往前走必须进行“跳跃”的时候。也就是i == cur。我们把对应的变量进行更新,实现“跳跃”。

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值