【LeetCode】121. 买卖股票的最佳时机
官方介绍文档
LeetCode说明连接:121. 买卖股票的最佳时机 - 力扣(LeetCode)
暴力破解法
既然是获取数组中,两个数之间的最大差值,可以使用暴力破解法。通过两个循环,计算最大值。
此种方法,在数组元素很多时,会判定超时。
class Solution {
public:
int maxProfit(vector<int>& prices) {
size_t nPriceSize = prices.size();
int nMaxProfit = 0;
for (size_t i = 0; i < nPriceSize - 1; i++)
{
for (size_t j = i + 1; j < nPriceSize; j++)
{
// 获取最大差值
nMaxProfit = std::max<int>(nMaxProfit, prices[j] - prices[i]);
}
}
return nMaxProfit;
}
};
复杂度分析
-
时间复杂度:O(n^2),循环运行n*(n-1)/2次
-
空间复杂度:O(1),只使用了常数变量
递归算法
减少输入的个数,既然要求先买后卖。
假设第二天卖,计算最大利润。
假设第三天卖,计算最大利润,然后与前两天的最大利润比较。。。依次类推,可以使用递归或动态规划的方法,获取上一次的情况。
class Solution {
public:
int maxProfit(vector<int>& prices) {
size_t nPriceSize = prices.size();
if (nPriceSize <= 1)
{
return 0;
}
int nMinPrice = prices[0];
int nMaxProfit = CalMaxProfit(prices, 1, nMinPrice);
return nMaxProfit;
}
int CalMaxProfit(vector<int>& prices, size_t nStart, int& nMinPrice)
{
if (nStart >= prices.size())
{
return 0;
}
int nCurPrice = prices[nStart];
int nCurProfit = nCurPrice - nMinPrice;
nMinPrice = std::min<int>(nMinPrice, nCurPrice);
return std::max<int>(CalMaxProfit(prices, nStart + 1, nMinPrice), nCurProfit);
}
};
复杂度分析
- 时间复杂度:O(n),递归n次。
- 空间复杂度:O(n),每次递归,都会创建几个常量使用。
动态规划
利用for
循环,省去递归的逻辑。减少开销。
动态规划公式:前i天的最大收益 = max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}
class Solution {
public:
int maxProfit(vector<int>& prices) {
size_t nPriceSize = prices.size();
int nMaxProfit = 0;
if (nPriceSize > 1)
{
int nMinPrice = prices[0];
for (size_t i = 1; i < nPriceSize; i++) // 从1开始即可,小于1时最大利润还是0
{
nMaxProfit = std::max<int>(nMaxProfit, prices[i] - nMinPrice);
nMinPrice = std::min<int>(nMinPrice, prices[i]);
}
}
return nMaxProfit;
}
};
复杂度分析
- 时间复杂度:O(n),只需要遍历一次。
- 空间复杂度:O(1),只使用了常数个变量。