1. 程式人生 > >LeetCode122.買賣股票的最佳時機II(C++實現)

LeetCode122.買賣股票的最佳時機II(C++實現)

題目描述:

最開始用暴力法解決,後來終於體會到什麼時間複雜度O(N^N)的……,自己測試陣列中有30個以上的元素,就需要等半天了,更別說測試用例中一千多個元素了。參考官方題解中的java程式碼後,用C++實現,特總結如下:

/*方法一:暴力法(時間超時)
暴力法需要計算所有可能的交易組合相對應的利潤,並找出其中最大的利潤;
在未處理的子序列中不斷使用遞迴函式去尋找最大利潤。
這種方法:不僅時間複雜度高-O(N^N),並且還使用了遞迴函式,非常不好;而且我發現
這種方法容易想到,但是實現起來可沒那麼容易。
*/
int calculateMaxProfit(vector<int> &prices, int start)
{//呼叫此calculateMaxProfit函式使用遞迴暴力法
	if(start >= prices.size())
		return 0;
	int maxProfit = 0;
	for (int i = start; i < prices.size() - 1; i++)
	{
		int tempProfit = 0;
		for (int j = i + 1; j < prices.size(); j++)
		{
			if (prices[i] < prices[j])
			{
				int profit = prices[j] - prices[i] + calculateMaxProfit(prices, j + 1);
				if(profit > tempProfit)
					tempProfit = profit;
			}
		}
		if(tempProfit > maxProfit)
			maxProfit = tempProfit;
	}
	return maxProfit;
}

/*方法二:峰谷法(官方題解)
把陣列中的數字以折線圖的形式反映,我們發現這就是有波峰和波谷的折線圖。而我們要找最大利潤,
其實就是我們要找到所有捱得最近的一組波谷和波峰差值的總和;
在這種情況下:只需要一次迴圈,不停的找某個波谷的值,然後緊接著找到離它最近的一個波峰的值,
他們的差值就是最大利潤的一部分;然後接下去再找下一組波谷和波峰;
時間複雜度:O(N)
*/
int maxProfit_peak_valley(vector<int>& prices) {
	int valley, peak, maxProfit = 0, index = 0;
	int len = prices.size();
	while(index < len - 1)
	{
		while (index < prices.size() - 1 && prices[index] >= prices[index + 1])
			index++;//尋找波谷
		valley = prices[index];
		while (index < prices.size() - 1 && prices[index] <= prices[index + 1])
			index++;//尋找波峰
		peak = prices[index];
		maxProfit += peak - valley;
	}
	return maxProfit;
}

/*方法三:一次遍歷(官方題解)
這種方法是峰谷法的改進:在從頭到尾迴圈遍歷陣列中每一個元素的時候,我們可以把處於升序排列的
子序列陣列元素的差值依次相加。
時間複雜度:O(N)
*/
int maxProfit(vector<int> prices)
{
	int maxProfir = 0;
	for (int i = 1; i < prices.size(); i++)
		if(prices[i] > prices[i	- 1])
			maxProfir += prices[i] - prices[i - 1];
	return maxProfir;
}