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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容