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)的空间复杂度,每次更新都尽可能延伸到最远距离,同时记录跳跃次数。

相关推荐
什巳5 小时前
JAVA练习309- 二叉树的层序遍历
java·数据结构·算法·leetcode
什巳7 小时前
JAVA练习306- 翻转二叉树
java·数据结构·算法·leetcode
smj2302_796826527 小时前
解决leetcode第3989题网格中保持一致的最大列数
python·算法·leetcode
巧克力男孩dd8 小时前
Python超典型练习题(第一次作业)
开发语言·python·算法
爱刷碗的苏泓舒8 小时前
平方根信息滤波:矩阵推导及 GNSS 参数估计应用
线性代数·算法·矩阵·gnss·参数估计·测量平差·平方根信息滤波
想做小南娘,发现自己是女生喵9 小时前
第 2 章 顺序表和 vector
java·数据结构·算法
艾醒10 小时前
2026年第29周(7.13-7.19)AI全复盘:技术突破、行业趣闻翻车、算力服务器商业动态
人工智能·算法
雪碧聊技术10 小时前
动态规划算法—01背包问题
算法·动态规划
bu_shuo10 小时前
c与cpp中的argc和argv
c语言·c++·算法
普贤莲花11 小时前
【2026年第29周---写于20260718】---整理,断舍离
程序人生·算法·生活