👨‍💻
LeetCode
  • Overview
  • Mixed / Design
    • Two Sum (4 Qs)
      • 0001. Two Sum
      • 0167. Two Sum II - Input array is sorted
      • 0170. Two Sum III - Data structure design
      • 0653. Two Sum IV - Input is a BST
    • 0015. 3Sum
    • 0208. Implement Trie (Prefix Tree)
  • String
    • 0014. Longest Common Prefix
    • 0028. Implement strStr()
    • 0344. Reverse String
    • 0151. Reverse Words in a String
    • 0557. Reverse Words in a String III
    • 0067. Add Binary
    • 0415. Add Strings
    • 0038. Count and Say
    • 0394. Decode String
    • 0953. Verifying an Alien Dictionary
    • 0020. Valid Parentheses
  • Linked List
    • 0002. Add Two Numbers
    • 0445. Add Two Numbers II
    • 0021. Merge Two Sorted Lists
    • 0023. Merge k Sorted Lists
    • 0206. Reverse Linked List
    • 0019. Remove Nth Node From End of List
  • Tree
    • 0098. Validate BST
    • 0100. Same Tree
    • 0101. Symmetric Tree
    • 0226. Invert Binary Tree
    • 0110. Balanced Binary Tree
    • 0250. Count Univalue Subtrees
    • 0654. Maximum Binary Tree
    • Binary Tree Traversal (7 Qs)
      • 0144. Preorder Traversal
      • 0145. Postorder Traversal
      • 0094. Inorder Traversal
      • 0102. Level Order Traversal
      • 0104. Maximum Depth
      • 0111. Minimum Depth
      • 1302. Deepest Leaves Sum
      • 0993. Cousins in Binary Tree
    • N-ary Tree Traversal (4 Qs)
      • 0589. Preorder Traversal
      • 0590. Postorder Traversal
      • 0429. Level Order Traversal
      • 0559. Maximum Depth
    • Convert to BST (2 Qs)
      • 0108. Convert Sorted Array to Binary Search Tree
      • 0109. Convert Sorted List to Binary Search Tree
  • Binary Search
    • 0704. Binary Search
    • 0035. Search Insert Position
    • 0278. First Bad Version
    • 0367. Valid Perfect Square
    • 0069. Sqrt(x)
    • 0875. Koko Eating Bananas
    • 1011. Capacity To Ship Packages Within D Days
    • 0410. Split Array Largest Sum
    • 0004. Median of Two Sorted Arrays
  • Two Pointer
    • 0075. Sort Colors
    • 0088. Merge Sorted Array
    • 0283. Move Zeroes
    • 0125. Valid Palindrome
    • 0011. Container With Most Water
    • 0026. Remove Duplicates from Sorted Array
  • Sliding Window
    • 0003. Longest Substring Without Repeating Characters
  • Sorting
    • 0148. Sort List
    • 0912. Sort an Array
    • 0215. Kth Largest in Array
  • Dynamic Programming
    • 0509. Fibonacci Number
    • 1137. N-th Tribonacci Number
    • 0055. Jump Game
    • 0053. Maximum Subarray
    • 0022. Generate Parentheses
    • 0005. Longest Palindromic Substring
    • 0072. Edit Distance
    • Buy and Sell Stock (6 Qs)
      • 0122. Best Time to Buy and Sell Stock II
      • 0714. Best Time to Buy and Sell Stock with Transaction Fee
      • 0121. Best Time to Buy and Sell Stock
      • 0309. Best Time to Buy and Sell Stock with Cooldown
      • 0123. Best Time to Buy and Sell Stock III
      • 0188. Best Time to Buy and Sell Stock IV
  • DFS / BFS
    • 0200. Number of Islands
  • Math
    • 0007. Reverse Integer
    • 0009. Palindrome Number
Powered by GitBook
On this page

Was this helpful?

  1. Dynamic Programming
  2. Buy and Sell Stock (6 Qs)

0188. Best Time to Buy and Sell Stock IV

Hard | Array + DP | 76 ms (96.01%), 14.1 MB (98.32%)

Previous0123. Best Time to Buy and Sell Stock IIINext0200. Number of Islands

Last updated 3 years ago

Was this helpful?

Source: GitHub:

You are given an integer array prices where prices[i] is the price of a given stock on the ith day, and an integer k.

Find the maximum profit you can achieve. You may complete at most k transactions.

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

Constraints:

  • 0 <= k <= 100

  • 0 <= prices.length <= 1000

  • 0 <= prices[i] <= 1000

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

Input: k = 2, prices = [3,2,6,5,0,3]
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.

We can use Final State Machine to solve the series of these problems.

Note that this problem limits us to have at most two transactions, so we need to maintain an array with the size "T+1" (one for day 0 initialization) to record MAX profit among one or two transactions.

Keep in mind that a complete transaction means "Buy + Sell". In other words, buying new stock equals creating a new transaction. Thus, when we calculate the hold state's profit with i transactions, for buying stock, we need to take the no-hold state's profit with "i-1" transaction.

  • Hold state means you hold the stock.

    • Since you don't have any stocks at the beginning, the profit at this state is initialized with negative infinity.

    • The profit in this state is calculated by: previous no-hold state's profit - current stock price (= buy) = no-hold state's profit w/ 'i-1' transactions - cur. stock price

  • No-Hold state means you do not hold any stocks.

    • Since you don't have any stocks at the beginning (you're initially at this state ), the profit at this state is initialized with 0.

    • The profit in this state is calculated by: previous hold state's profit + current stock price (= sell) = hold state's profit w/ 'i' transactions + cur. stock price

    • Return the profit at the no-hold state as the maximum profit since the hold state still has stock on hold.

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        # (base case)
        if len(prices) == 0 or len(prices) == 1: return 0

        # ==================================================
        #  Array + Dynamic Programming              (FSM)  =
        # ==================================================
        # time  : O(nk)
        # space : O(k)
        
        # '+1' for day 0 initialization
        T = k + 1
        hold, noHold = [float('-inf')] * T, [0] * T
        
        for price in prices:
            for i in range(1, T):
                prevHold, prevNoHold = hold[i], noHold[i]
                
                hold[i]   = max(prevHold,   noHold[i-1] - price)
                noHold[i] = max(prevNoHold, prevHold    + price)
                
        return noHold[-1]
class Solution {
    /**
     * @time  : O(nk)
     * @space : O(k)

    public int maxProfit(int k, int[] prices) {
        /* base case */
        if(prices.length == 0 || prices.length == 1) return 0;
        
        int T = k + 1;
        
        int[] hold = new int[T], noHold = new int[T];
        Arrays.fill(hold,   Integer.MIN_VALUE);
        Arrays.fill(noHold, 0);
        
        for(int price: prices) {
            for(int i=1 ; i<T ; i++) {
                int preHold = hold[i], preNoHold = noHold[i];
                
                hold[i]   = Math.max(preHold,   noHold[i-1] - price);
                noHold[i] = Math.max(preNoHold, preHold     + price);
            }
        }
        
        return noHold[T - 1];
    }
}
LeetCode - Best Time to Buy and Sell Stock IV
Solution / Performance