https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/
暴力
本題可以多次買賣股票,如果只允許一次買賣股票,整個暴力就是n2的算法,如果可以無限制買賣股票直接用普通的寫法不是很好寫,可以用遞歸來解決。先考慮只允許一次買賣的暴力解法,雙層循環,外層循環i代表買入股票的時機,內層j循環從i+1開始,代表買入股票后的股票價格,如果發現prices[j]>prices[i]就嘗試賣掉並和全局max比較,如果大於全局max就更改。但本題可以無限買賣股票,所以在一次買賣后還可以接着買賣,這樣問題就變化為了在i買入j賣出后,在j到prices.length的范圍內繼續買賣,原問題轉化為了子問題,這很遞歸。
每次i買入股票j賣出股票后,對j+1以后的股票遞歸調用,int s代表股票開始的位置。
這里用了兩個臨時變量來存儲可能的最大值。max代表全局最大值,放在最外層的循環,代表從索引s開始買賣股票能夠獲取的最大的利潤。maxProfit放在內層循環,當i等於s時,代表從s買股票能夠獲得的最大利潤,每次算出maxProfit用於和max比較並更新max。
public class maxProfit_122 { public int maxProfit(int[] prices) { return cal(prices,0); } public int cal(int[] prices,int s){ if (s>=prices.length){ return 0; } int max = 0; for (int i=s;i<prices.length;i++){ int maxProfit = 0; for (int j=i+1;j<prices.length;j++){ if (prices[j]>prices[i]){ int tempProfit = cal(prices, j + 1) + prices[j] - prices[i]; maxProfit = tempProfit>maxProfit?tempProfit:maxProfit; } } max = maxProfit>max?maxProfit:max; } return max; }
波峰波谷
因為買賣次數是無限的,所以把問題轉化為求整個股票價格序列中所有波峰和波谷之差之和。遍歷整個數組,找到波谷,找到波峰,相減。
先不考慮開始,假設現在處在循環之中。比較i和i+1,如果i大於i+1說明這是遞減區間,一直往下走,直到i不再大於i+1說明遞減區間結束,i不再大於i+1說明i<i+1,此時i的值為波谷,這個很簡單,導數異號說明來到了極值。用同樣的方法找到最大值,然后相減即為一次買賣的利潤。
其次關注初始條件的設置,low high都設置為Index等於0的數。如果數組的第一個區間是遞增的,那么low就是0。
class Solution { public int maxProfit(int[] prices) { if(prices.length == 0){ return 0; } int i = 0; int low = prices[0]; int high = prices[0]; int result=0; while (i<prices.length-1){ while (i<prices.length-1 && prices[i]>=prices[i+1]){ i++; } low = prices[i]; while (i<prices.length-1 && prices[i]<=prices[i+1]){ i++; } high = prices[i]; result+=high-low; } return result; } }