2024.06.30 刷题日记

121. 买卖股票的最佳时机

实例 1:

输入:[7,1,5,3,6,4]

输出:5

解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:

输入:prices = [7,6,4,3,1]

输出:0

解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

思路就是,一边遍历,一边更新 maxProfit,然后更新 历史最低价,并期望在未来能获得最大利润:

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int min = prices[0], maxProfit = 0;
        for (int price : prices) {
            maxProfit = price > min && price - min > maxProfit ? price - min
                                                               : maxProfit;
            min = price < min ? price : min;
        }
        return maxProfit;
    }
};

55. 跳跃游戏

示例 1:

输入:nums = [2,3,1,1,4]

输出:true

解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3

步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]

输出:false

解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0,所以永远不可能到达最后一个下标。

思路是一边遍历,一边更新 maxReach

cpp 复制代码
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int maxReach = 0;    // 最远可以到达的位置
        int n = nums.size(); // 数组的长度

        for (int i = 0; i < n; i++) {
            if (i > maxReach) {
                return false;
            }
            // 更新最远可以到达的位置
            maxReach = max(maxReach, i + nums[i]);
            if (maxReach >= n - 1) {
                return true;
            }
        }

        return false;
    }
};

45. 跳跃游戏 II

示例 1:

输入: nums = [2,3,1,1,4]

输出: 2

解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]

输出: 2

这道题目返回的是,最小的跳跃次数。应该思考,什么时候次数+1?答案是,当 i 遍历到currentEnd 的时候,就意味着还需要再跳一次。当然这个确定再跳一次后,可以提前结束。

cpp 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        int len = nums.size();
        if (len == 1) return 0;
        int maxReach = 0, times = 0;
        int currentEnd = 0;
        
        for (int i = 0; i < len; i++) {
            maxReach = max(maxReach, i + nums[i]);
            // 更新
            if (i == currentEnd) {
                times++;
                currentEnd = maxReach;
                if (currentEnd >= len - 1)
                    break;
            }
        }
        return times;
    }
};

总结

1. 买卖股票的最佳时机(LeetCode 121)

问题描述:找到一次交易(买入和随后的卖出)能获得的最大利润。

解题思路

  • 维护两个变量minPrice(迄今为止遇到的最低价格)和maxProfit(迄今为止可以获得的最大利润)。
  • 遍历数组 :对于数组中的每个价格,更新minPrice。计算如果在该价格卖出的利润,并更新maxProfit

代码实现:在单次遍历中同时更新这两个变量,保证了时间复杂度为O(n),空间复杂度为O(1)。

2. 跳跃游戏(LeetCode 55)

问题描述:判断你是否能够到达数组的最后一个位置。

解题思路

  • 维护一个变量 maxReach表示从当前或之前的索引最远能到达的位置。
  • 遍历数组 :如果当前索引超过了maxReach,说明存在一点使得无法前进到数组的更远位置,返回false。
  • 及时更新 :更新maxReach为当前索引加上在该索引处能跳的最远距离。

代码实现:时间复杂度为O(n),空间复杂度为O(1)。

3. 跳跃游戏 II(LeetCode 45)

问题描述:找出到达数组最后一个位置的最小跳跃次数。

解题思路

  • 类似宽度优先搜索 :维护当前跳跃可达的最远边界currentEnd和下一跳可能达到的最远距离maxReach
  • 遍历数组 :每次到达currentEnd时,意味着完成了一次跳跃,更新跳跃次数,并将currentEnd更新为maxReach
  • 预先判断 :如果在某次跳跃后maxReach已经大于或等于数组最后一个位置,则结束遍历,返回当前跳跃次数。

代码实现:保持O(n)的时间复杂度和O(1)的空间复杂度,每次更新都尽可能延伸到最远距离,同时记录跳跃次数。

相关推荐
AI街潜水的八角34 分钟前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple1 小时前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少1 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs111 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋2 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp2 小时前
Java:数据结构-枚举
java·开发语言·数据结构
昂子的博客2 小时前
基础数据结构——队列(链表实现)
数据结构
咕咕吖2 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎3 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu3 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法