LeetCode122.買賣股票的最佳時機II(C++實現)
阿新 • • 發佈:2018-12-12
題目描述:
最開始用暴力法解決,後來終於體會到什麼時間複雜度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; }