题目描述:
给定一个数组,它的第 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。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、暴利求解
运行结果:
代码描述
第一天买,然后选取后面一天卖。第二天买,然后选取后面一天卖。第三天买......最后留下最大值。数据量小时,还可以接受,测试数据一旦很大,时间复杂度是O(n^2),这个增长太可怕。
// 暴利求解。战绩惨不忍睹
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result = 0;
int len = prices.size();
if(len <= 1) return result;
for(int i = 0; i < len-1; ++i)
{
for(int j = i+1; j < len; ++j)
{
if(result < prices[j]-prices[i])
result=prices[j]-prices[i];
}
}
return result;
}
};
二、动态规划
运行结果
代码描述:
动态规划:前i天的最大收益 = max{前i-1天的最大收益,第i天的价格 - 前i-1天中的最小价格}
index | 0 | 1 | 2 | 3 | 4 | 5 |
val | 7 | 1 | 5 | 3 | 6 | 4 |
max/min | 0/7 | max(0, 1-7)/1 | max(0, 5-1)/1 | max(4, 3-1)/1 | max(4, 6-1)/1 | max(5, 4-1)/1 |
说明 | 初始状态 | max{当前max=0,当前max减去前面的最小值min=-6} 前两天的最小值min
|
发现一个规律:min 一直保留筛选过的数据的最小值(观察表中最小值的颜色,都是从前一组计算遗留下来的。),而max则一路保留差值的最大值。时间复杂度O(n)。
// 动态规划
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len <= 1) return 0;
int Min = prices[0], Max = 0;
for(int i = 1; i < len; ++i)
{
Max = max(Max, prices[i]-Min);
Min = min(Min, prices[i]);
}
return Max;
}
};