Bird
Raised Fist0
Interview Prepdp-grid-intervalsmediumAmazonMicrosoft

Triangle (Min Path Sum)

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize dp with last row

We start by copying the last row of the triangle into the dp array. This represents the base case where the minimum path sum starting at the bottom row is the element itself.

💡 Initializing dp with the last row sets the foundation for bottom-up calculation, as these values are known and do not depend on any further computations.
Line:dp = triangle[-1][:]
💡 The dp array now holds the minimum path sums for the bottom row, which are just the values themselves.
📊
Triangle (Min Path Sum) - Watch the Algorithm Execute, Step by Step
Watching the algorithm step-by-step reveals how dynamic programming builds solutions from smaller subproblems, making the minimum path sum clear without complex recursion.
Step 1/11
·Active fill★Answer cell
Initializing dp array
i\w0
i=02
i=134
i=2657
i=34183
dp init
Initializing dp array
i\w0
i=02
i=134
i=2657
i=34183
processing row 2
Item 0 - wt:6 val:7
i\w0
i=02
i=134
i=2757
i=34183
updating dp[0]
Item 1 - wt:5 val:6
i\w0
i=02
i=134
i=2767
i=34183
updating dp[1]
Item 2 - wt:7 val:10
i\w0
i=02
i=134
i=27610
i=34183
updating dp[2]
Initializing dp array
i\w0
i=02
i=134
i=27610
i=34183
processing row 1
Item 0 - wt:3 val:9
i\w0
i=02
i=194
i=27610
i=34183
updating dp[0]
Item 1 - wt:4 val:10
i\w0
i=02
i=1910
i=27610
i=34183
updating dp[1]
Initializing dp array
i\w0
i=02
i=1910
i=27610
i=34183
processing top row
Item 0 - wt:2 val:11
i\w0
i=011
i=1910
i=27610
i=34183
final dp[0]
Item 0 - wt:2 val:11
i\w0
i=011
i=1910
i=27610
i=34183
answer cell

Key Takeaways

✓ Bottom-up DP builds the solution from the known base case at the bottom row upwards.

This insight is hard to see from code alone because the recursion is implicit; watching dp update clarifies the process.

✓ Each dp cell depends only on the two adjacent cells below, showing the overlapping subproblems clearly.

Visualizing dependencies helps understand why the algorithm iterates bottom-up and how it avoids recomputation.

✓ The final answer is stored in dp[0] after processing the top row, representing the minimal path sum from apex to base.

Seeing the final dp array state confirms how the answer emerges from incremental updates.

Practice

(1/5)
1. You are given an array of balloons, each with a number representing coins. When you burst a balloon, you gain coins equal to the product of the balloon's number and its adjacent balloons' numbers. After bursting, the balloon disappears and adjacent balloons become neighbors. Which algorithmic approach guarantees finding the maximum coins you can collect by bursting all balloons in an optimal order?
easy
A. Greedy approach bursting the balloon with the highest number first
B. Sorting balloons and bursting them in ascending order
C. Dynamic programming using interval partitioning and considering the last balloon to burst in each interval
D. Simple recursion trying all burst orders without memoization

Solution

  1. Step 1: Understand problem structure

    The problem requires maximizing coins by bursting balloons in an order where each burst depends on adjacent balloons, which changes dynamically.
  2. Step 2: Identify suitable algorithm

    Greedy or sorting approaches fail because local choices don't guarantee global optimum. Simple recursion is correct but inefficient. Interval DP solves by considering subproblems defined by intervals and choosing the last balloon to burst in each interval, ensuring optimal substructure.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Interval DP handles overlapping subproblems and changing neighbors [OK]
Hint: Optimal substructure requires interval DP, not greedy [OK]
Common Mistakes:
  • Assuming greedy bursting yields max coins
  • Trying recursion without memoization
  • Ignoring interval-based subproblems
2. Given the following code for finding the cheapest flight within K stops, what is the returned value for the input below? Input: n = 3 flights = [[0,1,100],[1,2,100],[0,2,500]] src = 0 dst = 2 K = 1
def findCheapestPrice(n, flights, src, dst, K):
    INF = float('inf')
    prev = [INF] * n
    prev[src] = 0
    for _ in range(K + 1):
        curr = prev[:]
        for u, v, w in flights:
            if prev[u] != INF:
                curr[v] = min(curr[v], prev[u] + w)
        prev = curr
    return prev[dst] if prev[dst] != INF else -1

print(findCheapestPrice(n, flights, src, dst, K))
easy
A. 500
B. 200
C. -1
D. 100

Solution

  1. Step 1: Trace dp arrays for each iteration

    Initially prev = [0, inf, inf]. After first iteration (0 stops), curr updates cost to city 1 as 100 and city 2 as 500. After second iteration (1 stop), curr updates city 2 cost to min(500, 100 + 100) = 200.
  2. Step 2: Return final cost for destination

    prev[2] after K+1=2 iterations is 200, which is the cheapest cost with at most 1 stop.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    DP updates costs correctly over K+1 iterations [OK]
Hint: DP updates cost over K+1 iterations [OK]
Common Mistakes:
  • Returning direct edge cost ignoring stops
  • Off-by-one in iteration count
  • Confusing curr and prev arrays
3. Consider the following bottom-up DP code for the Strange Printer problem. What is the final returned value when the input string is "aba"?
easy
A. 3
B. 4
C. 1
D. 2

Solution

  1. Step 1: Compress input string "aba"

    Compression does not change string since no consecutive duplicates: s = "aba", n=3.
  2. Step 2: Trace dp table filling

    Base cases: dp[0][0]=1, dp[1][1]=1, dp[2][2]=1. For length=2: - dp[0][1]: dp[0][0]+1=2, s[0]!=s[1], so dp[0][1]=2 - dp[1][2]: dp[1][1]+1=2, s[1]!=s[2], so dp[1][2]=2 For length=3: - dp[0][2]: dp[0][1]+1=3 Check k=0: s[0]==s[2] ('a'=='a'), dp[0][0]+dp[1][1]=1+1=2 < 3, so dp[0][2]=2
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Output matches known minimal turns for "aba" [OK]
Hint: Check dp merging when s[k] == s[j] reduces turns [OK]
Common Mistakes:
  • Forgetting to merge intervals when characters match
4. What is the time complexity of the space-optimized bottom-up DP solution for the Cheapest Flights Within K Stops problem, given n cities, E flights, and maximum K stops?
medium
A. O(K * E) because each iteration relaxes all edges up to K+1 times
B. O(n^3) due to nested loops over cities and stops
C. O(E * log n) similar to Dijkstra's algorithm
D. O(n * K^2) due to dynamic programming over stops and cities

Solution

  1. Step 1: Identify loops in the algorithm

    The outer loop runs K+1 times, and the inner loop iterates over all E flights to relax edges.
  2. Step 2: Calculate total complexity

    Each iteration processes E edges, so total time is O(K * E). No nested loops over n^2 or log factors appear.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Algorithm iterates over edges K+1 times [OK]
Hint: Outer loop K+1 times, inner loop over E edges [OK]
Common Mistakes:
  • Confusing E with n^2
  • Assuming Dijkstra complexity
  • Counting recursion stack space
5. The following code attempts to implement the space-optimized DP solution for Maximal Square. Identify the line containing the subtle bug that causes incorrect results on some inputs.
def maximalSquare(matrix):
    if not matrix or not matrix[0]:
        return 0
    rows, cols = len(matrix), len(matrix[0])
    dp = [0] * (cols + 1)
    max_side = 0
    prev = 0
    for i in range(rows):
        for j in range(1, cols + 1):
            temp = dp[j]
            if matrix[i][j-1] == '1':
                dp[j] = 1 + min(dp[j], dp[j-1], prev)  # Bug here
                max_side = max(max_side, dp[j])
            else:
                dp[j] = 0
            prev = temp
    return max_side * max_side
medium
A. Line with 'dp[j] = 1 + min(dp[j], dp[j-1], dp[j-1])'
B. Line with 'temp = dp[j]'
C. Line with 'prev = temp'
D. Line with 'max_side = max(max_side, dp[j])'

Solution

  1. Step 1: Identify the DP recurrence

    The recurrence requires min(dp[j], dp[j-1], prev), but code uses dp[j-1] twice, missing 'prev'.
  2. Step 2: Understand impact

    Using dp[j-1] twice ignores the diagonal value 'prev', causing incorrect dp values and max square size.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Correct recurrence uses three distinct values [OK]
Hint: Check if all three DP states are used in min() [OK]
Common Mistakes:
  • Forgetting to use 'prev' in min()
  • Overwriting dp before using dependencies
  • Incorrect dp initialization
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard