1. 程式人生 > >Lintcode 買賣股票的最佳時機 系列問題1,2,3

Lintcode 買賣股票的最佳時機 系列問題1,2,3

題目1
假設有一個數組,它的第i個元素是一支給定的股票在第i天的價格。如果你最多隻允許完成一次買入和賣出,設計一個演算法來找出最大利潤。
樣例
給出一個數組樣例 [3,2,3,1,2], 返回 1

def maxProfit(self, prices):
        # write your code here
        n=len(prices)
        if n==0:
            return 0
        profit=0
        lowest=prices[0]
        for i in range(1,n):
            profit=max(prices[i]-lowest,profit)
            lowest=min(prices[i],lowest)

        return
profit

思路:
只關注歷史最低值lowest,在這個點買入,如果今後的某個點prices[i]買入使得profit比之前最大的profit大,那就更新profit。
也就是說不僅要有最小值點,後面還要有一個點使得profit比之前最大的profit大

問題2
假設有一個數組,它的第i個元素是一個給定的股票在第i天的價格。設計一個演算法來找到最大的利潤。你可以完成儘可能多的交易(多次買賣股票)。然而,你不能同時參與多個交易(你必須在再次購買前出售股票)。

def maxProfit(self, prices):
        # write your code here
n=len(prices) if n==0: return 0 profit=0 total=0 for i in range(n-1): if prices[i+1]>prices[i]: profit=prices[i+1]-prices[i] total=total+profit return total

思路:
只要相對於前一天有增量,就選擇賣出,雖然此時賣出並不是利潤最大化的最優解,但是通過累積的增量,比如[1,2,3], 2-1 + 3-2 和3-1的結果是一樣的 !

問題3
假設你有一個數組,它的第i個元素是一支給定的股票在第i天的價格。設計一個演算法來找到最大的利潤。你最多可以完成兩筆交易。

樣例
給出一個樣例陣列 [6,1,1,4,2,5], 返回 6

def maxProfit(self, prices):
        # write your code here
        n=len(prices)
        if n==0 or n==1:
            return 0

        profit=0
        left_lowest=prices[0]
        left_profit=[0]*n
        for i in range(1,n):
            profit=max(profit,prices[i]-left_lowest)
            left_lowest=min(left_lowest,prices[i])
            left_profit[i]=profit
            print('left_profit',profit)
            print('left_lowest',left_lowest)

        profit=0
        right_profit=[0]*n
        right_highest=prices[n-1]
        for i in range(n-2,-1,-1):
            profit=min(profit,prices[i]-right_highest)
            right_highest=max(right_highest,prices[i])
            right_profit[i]=-profit
            print('right_profit',profit)

        final_profit=0   
        for i in range(n):
            final_profit=max(final_profit,left_profit[i]+right_profit[i])
            #differnt from max subarray, buy and sell can occur on same day
            print('final_profit',final_profit)

        return final_profit

思路:
思路就是掃描線演算法,求兩個最大不重疊子陣列和的思路是一樣的,只是這裡,可以重疊一個元素(在同一天賣出再買入)。
從左往右的時候記錄最小值點,從右往左的時候記錄最大值點,另外,從右往左計算的是最小利潤,因為是個負值,比如[1,2,4,2,5], 左往右是4-1=3;而右往左是2-5=-3;當然也可以換一種方式寫這段程式碼,不是問題。