买卖股票的最佳时机(分治,dp)
买卖股票的最佳时机(分治,dp)
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
方法一:分治 O(nlgn)
要求最大利润,即p[j]-p[i]最大并且i < j. 将区间分为[l,mid-1],[mid+1,r]两部分。则有三种情况。
买入的股票和卖出的股票都在区间[l,mid-1]完成。
买入的股票和卖出的股票都在区间[mid+1,r]完成。
区间穿过mid,在左区间买入股票,在右区间卖出股票。
对于情况1和2,递归完成。
对于情况3,已知情况是区间穿过mid,即mid在区间里。我们可以从mid开始向左遍历找到最小的p[i],从mid开始向右遍历找到最大的p[j],p[j]-p[i]就是[i…mid…j]的最大利润。
最后对三种情况取最大值。
下面上代码。
class Solution {
public:
int Merge(vector<int>& prices, int l, int r)
{
if(l >= r)
{
return 0;
}
int mid = l+r>>1;
int x1 = Merge(prices,l,mid-1);
int x2 = Merge(prices,mid+1,r);
int l_min = prices[mid], r_max = prices[mid];
for(int i = mid;i >= 0;i--)
l_min = min(prices[i], l_min);
for(int i = mid;i <= r;i++)
r_max = max(r_max, prices[i]);
int x3 = r_max - l_min;
return max(max(x1,x2), x3);
}
int maxProfit(vector<int>& prices) {
int n = prices.size();
return Merge(prices,0,n-1);
}
};
方法二:dp O(n)
要求最大利润,即p[j]-p[i]最大并且i < j. 如果我们能知道前j个元素中的最小值,就可以找到买股票的起点。因此令dp[i]表示前i个元素中的最小值,可以得到这样的状态转移方程:
dp[0] = p[0],dp[i] = min(p[i], dp[i-1]).
那么a[i] - dp[i]就代表着前i个元素中的最大利润。我们枚举i,找到最大的i使得a[i]-dp[i]最大即可。
代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int> dp(prices.size(),0);
if(prices.size() == 0) return 0;
int n = dp.size(), ans = 0;
dp[0] = prices[0];
for(int i = 1;i < n;i++)
{
dp[i] = min(prices[i], dp[i-1]);
ans = max(ans, prices[i]-dp[i]);
}
return ans;
}
};
dp空间优化:
对于状态转移方程中的dp[i-1]的值,我们可以直接用一个Min代替数组的滚动。
下面上代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() == 0) return 0;
int n = prices.size(), ans = 0, Min = prices[0];
for(int i = 1;i < n;i++)
{
Min = min(prices[i], Min);
ans = max(ans, prices[i]-Min);
}
return ans;
}
};
————————————————
版权声明:本文为CSDN博主「Skyed.blue」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Skyed_blue/article/details/103164047
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
2015-10-24 AI顶级会议以及期刊