【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),只使用了常数个变量。
posted @ 2022-12-31 00:06  声音~  阅读(29)  评论(0)    收藏  举报