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

本文介绍了如何使用贪心算法解决LeetCode中的两道跳跃游戏题目(55和45)以及一道股票买卖问题(122),展示了如何找到局部最优解以实现整体最大利润或到达目标。每题都涉及时间复杂度和空间复杂度分析。
摘要由CSDN通过智能技术生成

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

题目链接:Leetcode 122.买卖股票的最佳时机 II
题目描述: 给定一个数组,它的第 i个元素是一支给定股票第i天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路: 本题可以利用贪心思想来做:局部最优:收集每天的正利润,全局最优:求得最大利润。
代码如下:

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;
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

Leetcode 55. 跳跃游戏

题目链接:Leetcode 55. 跳跃游戏
题目描述: 给你一个非负整数数组nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回true;否则,返回false
思路: 本题同样可以利用贪心来做:局部最优:每次取最大跳跃步数(确定最大覆盖范围),整体最优:根据整体最大范围判断其是否覆盖最后一个元素。

代码如下:

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(i + nums[i], cover);
            if (cover >= nums.size() - 1) //如果能到达终点返回true
                return true;
        }
        return false;
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

Leetcode 45.跳跃游戏 II

题目链接:Leetcode 45.跳跃游戏 II
题目描述: 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
其中数据范围满足:

  • 0 <= j <= nums[i]
  • i + j < n
    返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

思路: 本题看似和上道题类似,利用贪心思想解决,但是该如何用代码实现呢?首先思考什么情况下步数应该 + 1 +1 +1?由于题干保证一定可以跳到最后一个数字,也就是说我们只需要考虑跳到倒数第二个数字就可以了。

  1. 我们需要一个移动下标i0开始,根据当前数字确定可以跳到的范围(覆盖范围)
  2. 利用循环每次向右移动一位,并根据next=max(nums[i]+i,next)来更新覆盖范围,如果当前下标到达了之前记录的边界i==cur,则result++

代码如下:

class Solution {
public:
    int jump(vector<int>& nums) {
        int cur = 0;    //当前覆盖的最远距离下标
        int result = 0; //记录最大步数
        int next = 0;   //下一步覆盖的最远距离下标
        for (int i = 0; i < nums.size() - 1; i++) { //遍历到倒数第二个元素
            next = max(nums[i] + i, next);
            if (i == cur) {
                result++;
                cur = next; //更新当前覆盖范围
            }
        }
        return result;
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

总结: 贪心的题目难就难在该如何寻找某种决策,能使每次根据局部最优的决策,并且最终达到整体最优的结果。任重而道远啊!

最后,如果文章有错误,请在评论区或私信指出,让我们共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值