题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
题解
方法1:普通暴力遍历
算法
普通暴力遍历即每个人都能想到的方法,即每一对每一对的去遍历比较,遇到比max
还大的就更新max
。
代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0)
return 0;
int max = 0;
for (int i = 0; i < prices.size() - 1; i++) {
for (int j = i + 1; j < prices.size(); j++) {
int profit = prices[j] - prices[i];
if (profit > max) {
max = profit;
}
}
}
return max;
}
};
分析
时间复杂度:O(n2)级别,循环
n
(
n
−
1
)
2
\frac {n(n-1)}{2}
2n(n−1)次。LeetCode排名战胜15%提交。
空间复杂度:O(1)级别,因为只用了max
和profit
两个变量。
最大最小思想
算法
图源LeetCode官方题解
如果把输入的数组画成一个折线图,如上图所示,就可以看出,这个问题实际上是求数组当最小值在最大值的前头的时候
,最小值与最大值之差
的最大。
也就是说,对折线上的每一个点i
,求出点i
之前的最小值min
,求出点i
之后的最大值max
,并得出差值profit = max - min
,最后再得出总的最大profit
就是题解了。
代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0)
return 0;
int maxProfit = 0;
int minPrice = prices[0];
for (const auto& price : prices) {
if (price < minPrice)
minPrice = price;
int profit = price - minPrice;
if (profit > maxProfit)
maxProfit = profit;
}
return maxProfit;
}
};
分析
只需要循环一次,所以时间复杂度O(n),LeetCode排名战胜98%提交。
只用到三个变量,所以空间复杂度O(1)。