123/188. Best Time to Buy and Sell Stock III/IV (Hard)

Description:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

Example 1:

Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.


Solution:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        
        prices = [math.inf] + prices + [-math.inf]
        cache = []
        lag = 0
        for i in range(1,len(prices)-1):
            if prices[i] == prices[i+1]:
                lag += 1
                continue
            if prices[i] <= prices[i-1-lag] and prices[i] <= prices[i+1]:
                cache.append(prices[I])
            if prices[i] >= prices[i-1-lag] and prices[i] >= prices[i+1]:
                cache.append(prices[I])
            lag = 0
            
        # print(cache)
        if not cache:
            return 0
        if len(cache) == 2:
            return cache[1]-cache[0]

        left_min = 0
        left_ls = [cache[1]-cache[0]]
        for i in range(2,len(cache)-2,2):
            if cache[i] < cache[left_min]:
                left_min = I
            left_ls.append(max(cache[i+1] - cache[left_min], left_ls[-1]))
        # print(left_ls)
        
        cache2 = [-c for c in cache][::-1]
        # print(cache2)
        right_min = 0
        right_ls = [cache2[1]-cache2[0]]
        for i in range(2,len(cache2)-2,2):
            if cache2[i] < cache2[right_min]:
                right_min = I
            right_ls.append(max(cache2[i+1] - cache2[right_min], right_ls[-1]))
        right_ls = right_ls[::-1]
        # print(right_ls[::-1])
        
        return max([left_ls[i]+right_ls[i] for i in range(len(left_ls))])

Runtime: 76 ms, faster than 17.99% of Python3 online submissions for Best Time to Buy and Sell Stock III.
Memory Usage: 14.9 MB, less than 12.30% of Python3 online submissions for Best Time to Buy and Sell Stock III.


Description:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

Example 1:

Input: [2,4,1], k = 2
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.

Example 2:

Input: [3,2,6,5,0,3], k = 2
Output: 7
Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.


Solutions:

TLE solution:

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        if not prices or k == 0:
            return 0
        
        prices = [math.inf] + prices + [-math.inf]
        cache = []
        lag = 0
        for i in range(1,len(prices)-1):
            if prices[i] == prices[i+1]:
                lag += 1
                continue
            if prices[i] >= prices[i-1-lag] and prices[i] >= prices[i+1]:
                cache.append(prices[I])
            if prices[i] <= prices[i-1-lag] and prices[i] <= prices[i+1]:
                cache.append(prices[I])
            lag = 0
                
        # print(cache)
        if not cache:
            return 0
        if len(cache)//2 <= k:
            return sum([cache[i+1]-cache[i] for i in range(0,len(cache),2)])
        
        length = len(cache)//2
        dp = [[0 for i in range(length)] for j in range(length)]
        
        for i in range(length):
            dp[i][i] = cache[2*i+1] - cache[2*i]
            min_left = cache[2*I]
            for j in range(i+1,length):
                min_left = min(min_left,cache[2*j])
                dp[i][j] = max(dp[i][j-1], cache[2*j+1] - min_left)
            
        # for d in dp:
        #     print(d)
            
        def helper(start,k):
            if k == 0:
                return 0
            if k == 1:
                return dp[start][-1]
            
            cache = []
            for i in range(start,length-k+1):
                cache.append(dp[start][i] + helper(i+1,k-1))
            return max(cache)
            
        return helper(0,k)

Solution inspired by https://www.youtube.com/watch?v=oDhu5uGq_ic

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        if not prices or k == 0:
            return 0
        
        i = 1
        prices = [math.inf] + prices + [-math.inf]
        while i < len(prices)-1:
            while (i < len(prices)-1) and ((prices[i-1] < prices[i] and prices[i] < prices[i+1]) or (prices[i-1] > prices[i] and prices[i] > prices[i+1]) or (prices[i] == prices[i+1])):
                prices.pop(i)
            else:
                i += 1
        prices = prices[1:len(prices)-1]
        
        if k >= len(prices)//2:
            return sum([prices[i*2+1] - prices[i*2] for i in range(len(prices)//2)])
        
        last = [0 for i in range(len(prices))]
        for trans in range(1,k+1):
            curr = [0]
            max_diff = last[0] - prices[0]
            for day in range(1,len(prices)):
                max_diff = max(max_diff,last[day]-prices[day])
                curr.append(max([curr[-1],prices[day]+max_diff]))
            last = curr

        return last[-1]

Runtime: 96 ms, faster than 60.75% of Python3 online submissions for Best Time to Buy and Sell Stock IV.
Memory Usage: 14.5 MB, less than 15.65% of Python3 online submissions for Best Time to Buy and Sell Stock IV.

sample 36 ms submission: 沒看懂

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        h = []
        st = []
        v2, p2, n = 0, 0, len(prices)
        
        while p2 < n-1:
            v2 = p2
            while v2 < n-1 and prices[v2] >= prices[v2+1]:
                v2 += 1
            p2 = v2 + 1
            while p2 < n and prices[p2] >= prices[p2-1]:
                p2 += 1
            
            while st and prices[v2] < prices[st[-1][0]]:
                v1, p1 = st.pop()
                h.append(prices[p1-1] - prices[v1])
            
            while st and prices[p2-1] >= prices[st[-1][1]-1]:
                v1, p1 = st.pop()
                h.append(prices[p1-1] - prices[v2])
                v2 = v1
            
            st.append((v2,p2))
            
        h = heapq.nlargest(k, h)[::-1]
        # heapq.heapify(h)
        while st:
            v, p = st.pop()
            profit = prices[p-1] - prices[v]
            if len(h) < k:
                heapq.heappush(h, profit)
            else:
                heapq.heappushpop(h, profit)
        return sum(h)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酷师,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陪蜻,死亡現(xiàn)場離奇詭異虏杰,居然都是意外死亡怕吴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門停撞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓷蛙,“玉大人,你說我怎么就攤上這事戈毒〖桠” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵埋市,是天一觀的道長冠桃。 經(jīng)常有香客問我,道長道宅,這世上最難降的妖魔是什么食听? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮培己,結(jié)果婚禮上碳蛋,老公的妹妹穿的比我還像新娘。我一直安慰自己省咨,他們只是感情好肃弟,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著零蓉,像睡著了一般笤受。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敌蜂,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天箩兽,我揣著相機與錄音,去河邊找鬼章喉。 笑死汗贫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的秸脱。 我是一名探鬼主播落包,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摊唇!你這毒婦竟也來了咐蝇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤巷查,失蹤者是張志新(化名)和其女友劉穎有序,沒想到半個月后抹腿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡旭寿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年警绩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盅称。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡房蝉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出微渠,到底是詐尸還是另有隱情搭幻,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布逞盆,位于F島的核電站檀蹋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏云芦。R本人自食惡果不足惜俯逾,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舅逸。 院中可真熱鬧桌肴,春花似錦、人聲如沸琉历。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旗笔。三九已至彪置,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝇恶,已是汗流浹背拳魁。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撮弧,地道東北人潘懊。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像贿衍,于是被迫代替她去往敵國和親授舟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容