LintCode-買賣股票的最佳時(shí)機(jī)I、II、III

思路概述

I、只許購買一次股票。遍歷所有時(shí)間的股票價(jià)格,以當(dāng)前股票價(jià)格之前出現(xiàn)過的最低價(jià)作為買入價(jià),并計(jì)算出當(dāng)天價(jià)格出售的收益,與曾經(jīng)的最大收益對比,遍歷完即可的得到最大可能收益;
II、交易次數(shù)不限,但每次只能持有一只股票。就可以用貪心法,只要當(dāng)天價(jià)格高于前一天,就加入到收益之中去;
III、最多兩次購買股票。動(dòng)態(tài)規(guī)劃問題,可以以第i天未分界點(diǎn),計(jì)算前面的單次股票最大收益和后面股票的最大收益,然后求兩者和的最大值作為最終的收益。
IV、特殊的動(dòng)態(tài)規(guī)劃問題,Local[i][j]表示在到達(dá)第i天時(shí)最多可進(jìn)行j次交易并且最后一次交易在最后一天賣出的最大利潤,此為局部最優(yōu)。Global[i][j]為在到達(dá)第i天時(shí)最多可進(jìn)行j次交易的最大利潤,此為全局最優(yōu)。特別注意,遞推公式的max函數(shù)實(shí)際上代表了對過去狀態(tài)產(chǎn)生的多個(gè)結(jié)果進(jìn)行擇優(yōu)。

特殊動(dòng)態(tài)規(guī)劃問題公式

Local[i][j] = max(Local[i-1][j], Global[i-1][j-1]) + difference(狀態(tài)增益值)
Global[i][j] = max(Local[i][j], Global[i-1][j])
理解公式很重要。

I

描述

假設(shè)有一個(gè)數(shù)組,它的第i個(gè)元素是一支給定的股票在第i天的價(jià)格。如果你最多只允許完成一次交易(例如,一次買賣股票),設(shè)計(jì)一個(gè)算法來找出最大利潤。

樣例

給出一個(gè)數(shù)組樣例 [3,2,3,1,2], 返回 1

代碼

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        maxProfit = 0
        if len(prices) == 0:
            return maxProfit
        minPrice = prices[0]
        for i in range(1, len(prices)):
            minPrice = min(minPrice, prices[i])
            maxProfit = max(maxProfit, prices[i]-minPrice)
        return maxProfit

II

描述

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

樣例

給出一個(gè)數(shù)組樣例[2,1,2,0,1], 返回 2

代碼

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        # write your code here
        maxProfit = 0
        if len(prices) == 0:
            return maxProfit
        for i in range(1, len(prices)):
            maxProfit = maxProfit + max(0, prices[i]-prices[i-1])
        return maxProfit

III

描述

假設(shè)你有一個(gè)數(shù)組,它的第i個(gè)元素是一支給定的股票在第i天的價(jià)格。設(shè)計(jì)一個(gè)算法來找到最大的利潤。你最多可以完成兩筆交易。

樣例

給出一個(gè)樣例數(shù)組 [4,4,6,1,1,4,2,5], 返回 6

代碼

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        # write your code here
        if len(prices) <= 1:
            return 0
        ProfitLift = [0 for i in range(len(prices))]
        ProfitRight = [0 for i in range(len(prices))]
        minPrice = prices[0]
        for i in range(1, len(ProfitLift)):
            minPrice = min(minPrice, prices[i])
            ProfitLift[i] = max(ProfitLift[i-1], max(ProfitLift[i], prices[i]-minPrice))
        maxPrice = prices[-1]
        for i in reversed(range(1, len(ProfitRight))):
            maxPrice = max(maxPrice, prices[i])
            ProfitRight[i-1] = max(ProfitRight[i], max(ProfitRight[i-1], maxPrice-prices[i-1]))
        result = 0
        for i in range(0, len(prices)):
            result = max(result, ProfitLift[i] + ProfitRight[i])
        return result        

IV

描述

假設(shè)你有一個(gè)數(shù)組,它的第i個(gè)元素是一支給定的股票在第i天的價(jià)格。
設(shè)計(jì)一個(gè)算法來找到最大的利潤。你最多可以完成 k 筆交易。

樣例

給定價(jià)格 = [4,4,6,1,1,4,2,5], 且 k = 2, 返回 6.

挑戰(zhàn)

O(nk) 時(shí)間序列。

代碼

class Solution:
    """
    @param nums: A list of integers
    @param k: An integer denote to find k non-overlapping subarrays
    @return: An integer denote the sum of max k non-overlapping subarrays
    """
    def maxProfit(self, K, prices):
        # write your code here
        if len(prices) <=1:
            return 0
        elif K >= len(prices):
            result = 0
            for i in range(1, len(prices)):
                result = max(prices[i]-prices[i-1], 0) + result
            return result
        else:
            Local = [[0 for i in range(K + 1)] for i in range(len(prices) + 1)]
            Global = [[0 for i in range(K + 1)] for i in range(len(prices) + 1)]
    
            for i in range(1, len(prices)+1):
                for j in range(1, K+1):
                    if j*2 > i:
                        Local[i][j] = 0
                        Global[i][j] = 0
                    else:
                        Local[i][j] = max(Local[i-1][j], Global[i-1][j-1]) + (prices[i-1] - prices[i-2])
                        Global[i][j] = max(Local[i][j], Global[i-1][j])
            return max(Global[-1])

(優(yōu)化空間使用)

class Solution:
    """
    @param K: An integer
    @param prices: An integer array
    @return: Maximum profit
    """
    def maxProfit(self, K, prices):
        # write your code here
        if len(prices) <=1:
            return 0
        elif K >= len(prices):
            result = 0
            for i in range(1, len(prices)):
                result = max(prices[i]-prices[i-1], 0) + result
            return result
        else:
            Local = [[0 for j in range(K+1)] for i in range(2)]
            Global = [[0 for j in range(K+1)] for i in range(2)]
            
            for i in range(1, len(prices)+1):
                for j in range(1, K+1):
                    if j*2 >i:
                        Local[1][j] = 0
                        Global[1][j] = 0
                    else:
                        Local[1][j] = max(Local[0][j], Global[0][j-1]) + (prices[i-1] - prices[i-2])
                        Global[1][j] = max(Local[1][j], Global[0][j])
                for j in range(1, K+1):
                    Local[0][j] = Local[1][j]
                    Global[0][j] = Global[1][j]
            return max(Global[0])

題目來源

https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-i/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-ii/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iv/description

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容