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

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

        给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

视频讲解https://www.bilibili.com/video/BV1ev4y1C7na/?spm_id_from=333.999.0.0文章讲解https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII.html

  • 思路:分解
    • 假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。

      相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

    • 以每天为单位分解利润

    • 收集正利润

  • 代码: 
// 贪心解法
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;
    }
};

LeetCode 55. 跳跃游戏

        给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断 是否能够到达 最后一个位置。

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

视频讲解https://www.bilibili.com/video/BV1VG4y1X7kB/?spm_id_from=333.999.0.0文章讲解https://programmercarl.com/0055.%E8%B7%B3%E8%B7%83%E6%B8%B8%E6%88%8F.html#%E6%80%9D%E8%B7%AF

  • 思路:
    • 法一:跳跃覆盖范围究竟可不可以覆盖到终点
    • 法二:维护一个 result 数组,记录从每个下标能否到达终点,从后往前填充该数组;若跳不过连续的 false 位置,则为 false;返回 result[0] 即可。
  • 代码: 
// 法一:
class Solution {
public:
    bool canJump(vector<int>& nums) {
        // 最远能覆盖到的下标
        int cover = 0;
        for (int i = 0; i <= cover; ++i) {
            // 说明可以覆盖到终点了
            // 不用单独处理nums.size() == 1
            if (cover >= nums.size() - 1) {
                return true;
            }
            cover = max(i + nums[i], cover);
        }
        return false;
    }
};
// 法二:
class Solution {
public:
    bool canJump(vector<int>& nums) {
        vector<bool> result(nums.size(), false);
        result[nums.size() - 1] = true;
        int count = 0;
        for (int i = nums.size() - 2; i >= 0; --i) {
            // 能跳过false位置
            if (nums[i] > count) {
                result[i] = true;
                count = 0;
            } else {
                count++;
            }
        }
        return result[0];
    }
};

LeetCode 45.跳跃游戏II

        给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用 最少的跳跃次数 到达数组的最后一个位置。

视频讲解https://www.bilibili.com/video/BV1Y24y1r7XZ/?spm_id_from=333.999.0.0&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0045.%E8%B7%B3%E8%B7%83%E6%B8%B8%E6%88%8FII.html

  • 思路:维护两个变量①当前步能到达的最远位置②下一步能到达的最远位置
    • 当 i == 当前步能到达的最远位置👉需要再跳一步
    • 用下一步更新当前步,并且步数++
  • 代码: 
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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值