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

122.买卖股票的最佳时机II

1.做的时候感觉不难,自己也AC了,但是一下子说清楚为什么这样做并不容易。思考之后,我得到了一个自己感觉还算形象的解释。股票价格走势是一个折线图,两天之间的股票价格构成一条折线。我们只要在每一条上升折线的起始点买入,结束点卖出不放过任何一个赚钱的机会就能获得最大利润。当前最优推出整体最优,典型的贪心,折线模型类似于之前的摆动序列。(注:该算法源于我们站在上帝视角知道之后几天股票的价格,现实中并不可行)

cpp 复制代码
class Solution {
public://贪心:今天能赚就卖,明天能赚就买,不放弃任何一个赚钱的机会
    int maxProfit(vector<int>& prices) {
        int sum = 0;
        for (int i = 0; i + 1 < prices.size(); i++) {
            if ((prices[i + 1] - prices[i]) > 0)
                sum += prices[i + 1] - prices[i];
        }
        return sum;
    }
};

2.随想录版

cpp 复制代码
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;
    }
};

55. 跳跃游戏

1.贪心有时候就是朴素思想。本题我们一个朴素的思想就是如果当前位置跳不到最后位置,那我们就在当前位置能跳到的位置中选择能跳的最远的那个,这其实就是贪心!跳的最远的那个位置意味着之后有最多的选择,当前最优推出整体最优。

cpp 复制代码
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int sum = 0; // sum表示当前能跳跃到的最远下标
        //遍历当前元素能跳跃到的位置
        for (int i = 0; i <= sum; i++) {
            //如果当前位置能跳到最后直接返回true
            if (nums[i] >= nums.size() - i - 1)
                return true;
            //如果不能就尝试更新能跳到的最远的位置
            if (nums[i] + i >= sum)
                sum = nums[i] + i;
        }
        return false;
    }
};

2.随想录版,本质是一样的,cover代表能覆盖的跳跃范围。

cpp 复制代码
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
            cover = max(i + nums[i], cover);
            if (cover >= nums.size() - 1)
                return true; // 说明可以覆盖到终点了
        }
        return false;
    }
};

45.跳跃游戏II

1.其实本题的思路和之前是一样的,每次在能跳到的位置中选择能跳地最远的那个,那么最后的跳跃次数就是最小的那个。只不过本题相比于上一题的难度在于跳跃次数的统计,核心是每次跳到最远的那个位置跳跃次数+1,然后在当前位置能跳跃到的那个位置选择新的那个能跳的最远的位置。其中有些细节要注意,之前的cover是实时更新的,因为我们并不关注跳数。而现在,在遍历当前位置能跳到的位置中,遍历范围是要保持不变的。所以我们要用一个变量cover1接住cover值用于遍历,然后再在遍历过程中更新cover值,当找到新的最大cover值需要记录下次遍历的起始位置i。除此之外,当我们发现当前位置能跳到最后,跳跃次数也要+1。

cpp 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        if (nums.size() == 1)
            return 0;
        // cover表示当前跳跃下标最大值,初始值为数组初始位置
        int count = 0, cover = nums[0], i = 0;
        //遍历数组模拟跳跃过程,找跳数
        while (i < nums.size() - 1) {
            //跳跃下标能覆盖数组,跳数+1然后跳出循环
            if (cover >= nums.size() - 1) {
                count++;
                break;
            }
            int cover1 = cover; //复制cover值
            //利用复制的cover值更新cover值
            for (int j = i; j <= cover1; j++) {
                //找到跳的最远的那个位置并跳到这个位置
                if (nums[j] + j > cover) {
                    cover = nums[j] + j;
                    i = j;
                }
            }
            count++; //每跳一次,跳数+1
        }
        return count;
    }
};

2.随想录版,个人觉得随想录代码虽然简洁,但其实并不是那么容易理解。代码的逻辑应该是这样的:每次确定了起跳位置跳数+1,这也是i < nums.size() - 1的原因所在。因为题目保证一定能跳到最后,所以起跳位置最多只能是nums.size() - 2。这样做的好处是下标i不用回溯,因为当前覆盖的最远距离下标是不断增大的。

cpp 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        int curDistance = 0;  // 当前覆盖的最远距离下标
        int ans = 0;          // 记录走的最大步数
        int nextDistance = 0; // 下一步覆盖的最远距离下标
        for (int i = 0; i < nums.size() - 1;
             i++) { // 注意这里是小于nums.size() - 1,这是关键所在
            nextDistance =
                max(nums[i] + i, nextDistance); // 更新下一步覆盖的最远距离下标
            if (i == curDistance) { // 遇到当前覆盖的最远距离下标
                curDistance = nextDistance; // 更新当前覆盖的最远距离下标
                ans++;
            }
        }
        return ans;
    }
};

今日总结:我跳!

相关推荐
m0_748251722 天前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
gantengsheng2 天前
基于51单片机和OLED12864的小游戏《贪吃蛇》
单片机·嵌入式硬件·游戏·51单片机
264玫瑰资源库2 天前
从零开始C++棋牌游戏开发之第三篇:游戏的界面布局设计
开发语言·c++·python·游戏·pygame·源代码管理
264玫瑰资源库2 天前
从零开始C++游戏开发之第七篇:游戏状态机与回合管理
开发语言·c++·游戏
windwind20002 天前
游戏关卡设计方法的杂感
游戏·关卡设计
白乐天_n3 天前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏
这是我583 天前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
tealcwu3 天前
【游戏设计原理】21 - 解谜游戏的设计
游戏·游戏策划
清梦20203 天前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法
tealcwu3 天前
【游戏设计原理】22 - 石头剪刀布
游戏·游戏策划