您现在的位置是:首页 >技术杂谈 >代码随想录算法训练营第三十二天| 122.买卖股票的最佳时机II 、55. 跳跃游戏 、 45.跳跃游戏II网站首页技术杂谈

代码随想录算法训练营第三十二天| 122.买卖股票的最佳时机II 、55. 跳跃游戏 、 45.跳跃游戏II

菜鸟的Zoom之旅 2024-10-02 12:01:05
简介代码随想录算法训练营第三十二天| 122.买卖股票的最佳时机II 、55. 跳跃游戏 、 45.跳跃游戏II

买卖股票的最佳时机

题目链接:力扣

把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑

 局部最优:收集每天的正利润,全局最优:求得最大利润。

class Solution {
public:

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

跳跃游戏 

题目链接:力扣

这道题感觉是有难度的,看了题解也要懵半天,绕了半天才绕出来。

其实跳几步无所谓,关键在于可跳的覆盖范围。不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。这个范围内,别管是怎么跳的,反正一定可以跳过来。

那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!

贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。
而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。
如果 cover 大于等于了终点下标,直接 return true 就可以了。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        if(nums.size() == 1)
        return true;

        int cover = 0;

        for(int i=0;i<=cover;i++)
        {
           cover = max(i+nums[i],cover);
           if(cover >= nums.size()-1)
           return true;
        }

        return false;

    }
};

跳跃游戏II  

题目链接:力扣

 要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!
这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖

如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。

class Solution {
public:
    int jump(vector<int>& nums) {

      if(nums.size()<=1)
      return 0;
       
       int cur = 0;   //当前覆盖范围
       int next = nums[0];  //下一步覆盖范围
       int count=0;

       for(int i= 0; i<=cur; i++)
       {
           next = max(i+nums[i],next);
           if(i == cur)     //一旦当前的覆盖范围到尽头了 就启动next作为下一个覆盖范围
             { cur = next; count++;}

           if(cur >= nums.size()-1) break;
       }

       return count;

    }
};
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。