最大子數組問題:一個整數數組中的元素有正有負,在該數組中找出一個連續子數組,要求該連續子數組中各元素的和最大,並返回該最大值.python
求解最大子數組問題用Kadane's algorithm。 卡登算法的思想是,給定一個數組A,假如咱們已經知道了以數組第i個位置結尾的最大子數組爲\(B_i\),那麼在第i+1個位置結尾的最大子數組要麼包含\(B_i\),要麼不包含\(B_i\),若是將\(B\)看做是動態規劃當中的狀態,那麼狀態轉移方程是:$B_{i+1} = max (A_i, A_i + B_i) $算法
好比要計算數組 x = [-2, 1, -3, 4, -1, 2, 1, -5, 4] 的最大子數組,第一個位置的最大和爲-2,第2個位置的最大和爲max(1,-2+1) = 1,第三個位置最大和爲max(-3,-3+1) = -2,那麼依次類推,能夠求出來以第i個位置結尾的最大和分別爲
[0 , 1, -2, 4, 3, 5, 6, 1, 5]。數組
具體的算法是這樣的:優化
def max_subarray(arr): current_max_sum = max_sum = 0 for i in arr: current_max_sum = max(i, current_max_sum+i) max_sum = max(current_max_sum, max_sum) return max_sum
買賣股票的最佳時機spa
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。若是你最多隻容許完成一筆交易(即買入和賣出一支股票),設計一個算法來計算你所能獲取的最大利潤。注意你不能在買入股票前賣出股票。設計
示例 1:code
輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5。注意利潤不能是 7-1 = 6, 由於賣出價格須要大於買入價格。ip
示例 2:leetcode
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種狀況下, 沒有交易完成, 因此最大利潤爲 0。get
直接將後一天的股票價格減去前一天的股票價格,表示第i-1天買入而且在第i天賣出得到的利潤。而後求一個連續的利潤,使得和最大,那麼這個問題轉換爲求最大子數組問題。
好比對於[7,1,5,3,6,4],用後一天的價格減去前一天的價格,並把第一天的值置爲0,天天能夠得到的利潤爲:[0,-6,4,-2,3,-2]
Python代碼以下:
class Solution: def maxProfit(self, prices): """ :type prices: List[int] :rtype: int """ for i in range(len(prices)-1, 0, -1): prices[i] = prices[i] - prices[i-1] max_profits = 0 current_profits = 0 for i in prices[1:]: current_profits = max(current_profits+i, 0) max_profits = max(max_profits, current_profits) return max_profits
關於程序的說明:
對於程序的第13行,程序能夠寫爲current_profits = max(current_profits+i, i),這對於計算結果沒問題,可是對於計算current_profits的值會有影響。試想一下當輸入爲[3,2,1]的時候,通過處理之後數組變爲了[3,-1,-1],那麼current_profits,會計算出來-1,-1這樣的值,可是這是不可能的,由於咱們徹底能夠不買,使用0值就能夠了,因此將這裏替換爲current_profits = max(current_profits+i, 0),
將上面的代碼優化一下,能夠一遍來完成。current_profits = max(0, current_profits+prices[i]-prices[i-1])
class Solution: def maxProfit(self, prices): """ :type prices: List[int] :rtype: int """ max_profits = 0 current_profits = 0 for i in range(1, len(prices)): current_profits = max(0, current_profits + prices[i] - prices[i-1]) max_profits = max(max_profits, current_profits) return max_profits
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。設計一個算法來計算你所能獲取的最大利潤。你能夠儘量地完成更多的交易(屢次買賣一支股票)。注意:你不能同時參與多筆交易(你必須在再次購買前出售掉以前的股票)。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 7
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出,這筆交易所能得到利潤 = 5-1 = 4 。隨後,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能得到利潤 = 6-3 = 3 。
示例 2:
輸入: [1,2,3,4,5]
輸出: 4
解釋: 在第 1 天(股票價格 = 1)的時候買入,在第 5 天 (股票價格 = 5)的時候賣出,這筆交易所能得到利潤 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接連購買股票,以後再將它們賣出。由於這樣屬於同時參與了多筆交易,你必須在再次購買前出售掉以前的股票。
示例 3:
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種狀況下, 沒有交易完成, 因此最大利潤爲 0。
貪心算法走一波,貪心算法能夠解決這個問題,只要當前的價格比昨天的價格高,那麼就計算一次收益,最終的收益和就是可以獲取的最大的收益。
Python代碼以下:
class Solution: def maxProfit(self, prices): """ :type prices: List[int] :rtype: int """ res = 0 for i in range(1, len(prices)): diff = prices[i] - prices[i-1] if diff > 0: res += diff return res