Bird
Raised Fist0
Interview Prepdp-grid-intervalshardAmazonGoogle

Zuma Game (Min Moves to Clear)

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize hand count and memo dictionary

Count the balls in hand and prepare memoization storage to cache results for subproblems.

💡 Counting hand balls upfront allows quick checks on availability during recursion.
Line:hand_count = Counter(hand) memo = {}
💡 Hand ball counts are essential for deciding if insertion is possible at each step.
📊
Zuma Game (Min Moves to Clear) - Watch the Algorithm Execute, Step by Step
Watching each insertion attempt and recursive call reveals how interval DP breaks down the problem and why some states are impossible to clear.
Step 1/20
·Active fill★Answer cell
Item 0 - wt:0 val:0
i\w012345
i=0??????
Item 0 - wt:0 val:0
i\w012345
i=0WRRBBW
full board
Item 0 - wt:0 val:0
i\w012345
i=0WRRBBW
'W' group
Item 0 - wt:0 val:0
i\w012345
i=0WRRBBW
not enough 'W' balls
Item 1 - wt:0 val:0
i\w012345
i=0WRRBBW
'RR' group
Item 1 - wt:0 val:0
i\w012345
i=0WRRBBW
insert 'R' ball
Item 1 - wt:0 val:0
i\w012345
i=0WBBBW?
board after removal
Item 1 - wt:0 val:0
i\w012345
i=0WBBBW?
recursive call
Item 0 - wt:0 val:0
i\w01234
i=0WBBBW
not enough 'W' balls
Item 1 - wt:0 val:0
i\w01234
i=0WW???
remove 'BBB'
Item 0 - wt:0 val:0
i\w01
i=0WW
recursive call
Item 0 - wt:0 val:0
i\w01
i=0WW
not enough 'W' balls
Item 0 - wt:0 val:0
i\w01
i=0-1?
no solution
Item 1 - wt:0 val:0
i\w012345
i=0WBBBW-1
no solution
Item 3 - wt:0 val:0
i\w012345
i=0WRRBBW
'BB' group
Item 3 - wt:0 val:0
i\w012345
i=0WRRW??
board after removal
Item 0 - wt:0 val:0
i\w0123
i=0WRRW
recursive call
Item 1 - wt:0 val:0
i\w0123
i=0WRRW
insert 'R' ball
Item 1 - wt:0 val:0
i\w01
i=0WW
board after removal
Item 0 - wt:0 val:0
i\w012345
i=0-1?????
final no solution

Key Takeaways

✓ Interval DP breaks the problem into smaller substrings and uses memoization to avoid recomputation.

This is hard to see from code alone because recursion and memoization interplay is subtle.

✓ The algorithm tries all groups and possible insertions, pruning impossible paths early.

Visualizing each insertion attempt clarifies why some states fail and others succeed.

✓ Chain reactions from removing groups simplify the board and reduce problem size.

Watching remove_consecutive in action reveals how the board changes dynamically.

Practice

(1/5)
1. Consider the following Python function implementing the minimum falling path sum using bottom-up DP:
def minFallingPathSum(matrix):
    n = len(matrix)
    dp = matrix[0][:]

    for i in range(1, n):
        new_dp = [0]*n
        for j in range(n):
            best = dp[j]
            if j > 0:
                best = min(best, dp[j-1])
            if j < n - 1:
                best = min(best, dp[j+1])
            new_dp[j] = matrix[i][j] + best
        dp = new_dp

    return min(dp)

matrix = [[2,1,3],[6,5,4],[7,8,9]]
print(minFallingPathSum(matrix))
What is the output of this code?
easy
A. 12
B. 13
C. 14
D. 15

Solution

  1. Step 1: Trace dp after first row

    dp = [2, 1, 3]
  2. Step 2: Compute dp for second row

    For i=1: - j=0: best = min(dp[0], dp[1]) = min(2,1) = 1 -> new_dp[0] = 6 + 1 = 7 - j=1: best = min(dp[1], dp[0], dp[2]) = min(1,2,3) = 1 -> new_dp[1] = 5 + 1 = 6 - j=2: best = min(dp[2], dp[1]) = min(3,1) = 1 -> new_dp[2] = 4 + 1 = 5 So new_dp = [7, 6, 5]
  3. Step 3: Compute dp for third row

    For i=2: - j=0: best = min(new_dp[0], new_dp[1]) = min(7,6) = 6 -> new_dp[0] = 7 + 6 = 13 - j=1: best = min(new_dp[1], new_dp[0], new_dp[2]) = min(6,7,5) = 5 -> new_dp[1] = 8 + 5 = 13 - j=2: best = min(new_dp[2], new_dp[1]) = min(5,6) = 5 -> new_dp[2] = 9 + 5 = 14 So new_dp = [13, 13, 14]
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Minimum of last dp row is 13 [OK]
Hint: Trace dp row by row, pick min at end [OK]
Common Mistakes:
  • Off-by-one in indices
  • Using old dp instead of new_dp values
2. You are given a grid where some cells are blocked and others are free. You need to find the number of unique paths from the top-left corner to the bottom-right corner, moving only down or right, but you cannot pass through blocked cells. Which algorithmic approach guarantees an efficient and correct solution for this problem?
easy
A. Dynamic Programming that builds solutions using previously computed subproblems while skipping blocked cells
B. Pure brute force recursion exploring all paths without memoization
C. Greedy algorithm that always moves right if possible, else down
D. Dijkstra's shortest path algorithm treating grid cells as graph nodes

Solution

  1. Step 1: Understand problem constraints

    The problem requires counting all unique paths avoiding obstacles, which involves overlapping subproblems and optimal substructure.
  2. Step 2: Identify suitable algorithm

    Dynamic Programming efficiently computes the number of paths by reusing results and handling obstacles by zeroing paths through blocked cells.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    DP handles obstacles and overlapping subproblems correctly [OK]
Hint: DP handles obstacles and overlapping subproblems correctly [OK]
Common Mistakes:
  • Thinking greedy can find all paths
  • Using brute force without pruning
  • Confusing shortest path with counting paths
3. Consider the following Python code implementing the space-optimized DP solution for counting unique paths with obstacles. Given the input grid below, what is the value of the dp array after processing the second row (i=1)? Input grid: [[0,0,0], [0,1,0], [0,0,0]]
def uniquePathsWithObstacles(obstacleGrid):
    m, n = len(obstacleGrid), len(obstacleGrid[0])
    dp = [0]*n
    dp[0] = 1 if obstacleGrid[0][0] == 0 else 0
    for i in range(m):
        for j in range(n):
            if obstacleGrid[i][j] == 1:
                dp[j] = 0
            else:
                if j > 0:
                    dp[j] += dp[j-1]
    return dp[-1]
easy
A. [1, 1, 1]
B. [1, 1, 0]
C. [1, 0, 0]
D. [1, 0, 1]

Solution

  1. Step 1: Initialize dp after first row (i=0)

    dp starts as [1,0,0]. After processing first row (all zeros), dp updates to [1,1,1].
  2. Step 2: Process second row (i=1)

    At j=0, obstacleGrid[1][0]=0, dp[0] remains 1.
    At j=1, obstacleGrid[1][1]=1 (obstacle), dp[1] set to 0.
    At j=2, obstacleGrid[1][2]=0, dp[2] += dp[1] -> dp[2] = 1 + 0 = 1.
    Resulting dp: [1, 0, 1]
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    dp correctly zeroes obstacle cell and accumulates paths [OK]
Hint: Obstacles zero dp cells, dp[j] accumulates from dp[j-1] [OK]
Common Mistakes:
  • Forgetting to zero dp[j] on obstacle
  • Mis-updating dp[j] before dp[j-1]
  • Confusing row and column indices
4. You need to find the number of distinct ways to move from the top-left corner to the bottom-right corner of an m x n grid, moving only down or right at each step. Which algorithmic approach guarantees an efficient and optimal solution for this problem?
easy
A. Pure brute force recursion exploring all possible paths without memoization
B. Greedy algorithm that always moves towards the direction with fewer remaining steps
C. Dynamic Programming that builds solutions from smaller subproblems using a grid-based state representation
D. Divide and conquer by splitting the grid into quadrants and combining results

Solution

  1. Step 1: Understand problem constraints

    The problem requires counting all unique paths with only right and down moves, which naturally forms overlapping subproblems.
  2. Step 2: Identify suitable approach

    Dynamic Programming efficiently solves overlapping subproblems by storing intermediate results, unlike greedy or pure recursion which are either incorrect or inefficient.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    DP uses subproblem reuse -> optimal and efficient [OK]
Hint: Counting paths with overlapping subproblems -> DP [OK]
Common Mistakes:
  • Thinking greedy can find all paths
  • Using pure recursion without memoization
5. The following code attempts to compute the number of unique paths in an m x n grid using a space-optimized DP approach:
def uniquePaths(m, n):
    dp = [1] * n
    for i in range(1, m):
        for j in range(1, n):
            dp[j] = dp[j] + dp[j]
    return dp[-1]
What is the bug in this code?
medium
A. Line 3 should start loop from 0 instead of 1
B. Line 4 incorrectly doubles dp[j] instead of adding dp[j-1]
C. Line 5 should return dp[0] instead of dp[-1]
D. Line 2 initializes dp with wrong size

Solution

  1. Step 1: Analyze inner loop update

    Line 4 updates dp[j] by adding dp[j] to itself, doubling the value instead of adding dp[j-1].
  2. Step 2: Identify correct update

    The correct update is dp[j] += dp[j - 1] to accumulate paths from left and top cells.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Doubling dp[j] breaks path count logic -> bug at line 4 [OK]
Hint: Check dp update uses dp[j-1], not dp[j] twice [OK]
Common Mistakes:
  • Using dp[j] + dp[j] instead of dp[j] + dp[j-1]
  • Off-by-one errors in loops
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