{x}
blog image

Maximum Profit From Trading Stocks

Solution Explanation:

The problem asks to find the maximum profit achievable by buying and selling stocks, given a budget constraint. We are provided with two arrays, present and future, representing the current and future prices of stocks, respectively. We can buy each stock at most once.

The most efficient approach to solve this problem is using dynamic programming. We can model this as a 0/1 knapsack problem, where the "weight" of an item is the current price of a stock and its "value" is the profit from that stock (future price - current price). The knapsack capacity is our budget.

Approach:

Both solutions use dynamic programming, but Solution 2 is optimized for space complexity.

Solution 1 (DP with 2D array):

This solution uses a 2D DP table f where f[i][j] represents the maximum profit achievable using the first i stocks and a budget of j.

  • The base case is f[0][j] = 0 for all j, meaning no profit if no stocks are considered.

  • The recurrence relation is: f[i][j] = max(f[i-1][j], f[i-1][j - present[i-1]] + future[i-1] - present[i-1])

    • f[i-1][j] represents not buying the i-th stock.
    • f[i-1][j - present[i-1]] + future[i-1] - present[i-1] represents buying the i-th stock, if we have enough budget (j >= present[i-1]) and the profit from that stock is positive (future[i-1] > present[i-1]).
  • The final answer is f[n][budget], where n is the number of stocks.

Solution 2 (DP with 1D array):

This solution optimizes space complexity by using a 1D DP array f where f[j] represents the maximum profit achievable with a budget of j. It iterates through the stocks and updates the f array iteratively.

  • The iteration goes from budget down to a (the current stock price). This ensures that when considering a stock, we use the previously calculated maximum profit without that stock.
  • f[j] = max(f[j], f[j - a] + b - a) updates the maximum profit for budget j considering whether to buy the current stock or not.

Time and Space Complexity:

Solution 1:

  • Time Complexity: O(n * budget), where n is the number of stocks and budget is the given budget. This is because we iterate through the DP table.
  • Space Complexity: O(n * budget), due to the 2D DP table.

Solution 2:

  • Time Complexity: O(n * budget). Similar to Solution 1, but with a single loop instead of nested loops.
  • Space Complexity: O(budget), due to the 1D DP array. This is a significant improvement over Solution 1.

Code Examples (Python):

Solution 1 (2D DP):

class Solution:
    def maximumProfit(self, present: List[int], future: List[int], budget: int) -> int:
        n = len(present)
        f = [[0] * (budget + 1) for _ in range(n + 1)]
        for i in range(1, n + 1):
            for j in range(budget + 1):
                f[i][j] = f[i - 1][j]
                if j >= present[i - 1]:
                    f[i][j] = max(f[i][j], f[i - 1][j - present[i - 1]] + future[i - 1] - present[i - 1])
        return f[n][budget]
 

Solution 2 (1D DP):

class Solution:
    def maximumProfit(self, present: List[int], future: List[int], budget: int) -> int:
        f = [0] * (budget + 1)
        for p, fut in zip(present, future):
            for j in range(budget, p - 1, -1):
                f[j] = max(f[j], f[j - p] + fut - p)
        return f[budget]
 

Both solutions correctly solve the problem; Solution 2 is preferred due to its better space complexity. The choice between them depends on the specific constraints of the problem (memory limits, etc.).