☰
【动态规划-1】121.买卖股票的最佳时机
2026/10/9 2:53:30 网站建设 项目流程

题目描述:

给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。

你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回0。

示例 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。

解题思路:

方法一:贪心(维护最低价格)

核心思路:

对于每一天,如果在这一天卖出,最大利润 =当天价格 - 之前的最低价格。

所以只需要:

  1. 维护历史最低价格minPrice

  2. 每天计算prices[i] - minPrice,更新最大利润

  3. 更新minPrice = min(minPrice, prices[i])

具体过程示例:

prices = [7,1,5,3,6,4]

iprices[i]minPrice当天利润maxProfit
07700
11100
25144
33124
46155
54135

结果:5✅

代码实现:

class Solution { public: int maxProfit(vector<int>& prices) { int minPrice = INT_MAX; int maxProfit = 0; for (int price : prices) { if (price < minPrice) { minPrice = price; // 更新最低价格 } else { maxProfit = max(maxProfit, price - minPrice); // 更新最大利润 } } return maxProfit; } };

更简洁的写法:

class Solution { public: int maxProfit(vector<int>& prices) { int minPrice = INT_MAX, maxProfit = 0; for (int price : prices) { minPrice = min(minPrice, price); maxProfit = max(maxProfit, price - minPrice); } return maxProfit; } };

复杂度分析:

维度复杂度说明
时间复杂度O(n)一次遍历
空间复杂度O(1)只用两个变量

关键细节:

1. 为什么maxProfit初始为 0?

因为如果股票一直跌,不买就是最大利润(0),不会亏本。

2. 为什么先更新minPrice再计算利润?

因为买入必须在卖出之前。先更新minPrice保证用的是今天之前的最低价格。

cpp

minPrice = min(minPrice, price); // 先更新最低价 maxProfit = max(maxProfit, price - minPrice); // 再算利润

如果反过来,可能会用当天的价格买入和卖出,利润为 0,逻辑不对。

3. 和「买卖股票的最佳时机 II」的区别

题目区别
121. 买卖股票 I只能买卖一次
122. 买卖股票 II可以买卖多次

122 题:只要后一天比前一天高,就累加利润。

方法二:动态规划

思路:

维护两个状态:

  • dp[i][0]:第 i 天不持有股票的最大利润

  • dp[i][1]:第 i 天持有股票的最大利润

代码实现:

class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); vector<vector<int>> dp(n, vector<int>(2, 0)); dp[0][0] = 0; // 不持有 dp[0][1] = -prices[0]; // 持有(买入) for (int i = 1; i < n; i++) { dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]); // 卖出 dp[i][1] = max(dp[i-1][1], -prices[i]); // 买入 } return dp[n-1][0]; } };

空间优化:

class Solution { public: int maxProfit(vector<int>& prices) { int hold = -prices[0]; // 持有股票 int notHold = 0; // 不持有股票 for (int i = 1; i < prices.size(); i++) { notHold = max(notHold, hold + prices[i]); // 卖出 hold = max(hold, -prices[i]); // 买入 } return notHold; } };

复杂度:时间 O(n),空间 O(1)

两种方法对比:

方法时间复杂度空间复杂度推荐度
贪心(维护最低价)O(n)O(1)⭐⭐⭐⭐⭐
动态规划O(n)O(1)⭐⭐⭐⭐

总结:

要点说明
核心思想维护历史最低价,每天计算利润
关键操作minPrice = min(minPrice, price); maxProfit = max(maxProfit, price - minPrice);
时间复杂度O(n)
空间复杂度O(1)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询