AlgoMaster Logo

Candy Crush

mediumFrequencyUpdated August 29, 2026

Understanding the Problem

This is a simulation problem: implement the elimination mechanic from Candy Crush. We repeat two operations until the board stabilizes: find all groups of three or more identical candies in a row (horizontally or vertically), then crush them all at once and let gravity pull the remaining candies downward.

Crushing must happen simultaneously. You can't crush one group, drop, then look for the next group in the same iteration. All crushable candies in a given round must be identified before any of them are removed. After removal and gravity, you scan again, and the process repeats until a full scan finds nothing to crush.

The problem breaks down into three sub-problems that we loop over: mark (find all crushable candies), crush (set them to zero), and drop (apply gravity column by column). Once a full mark phase finds zero candidates, the board is stable.

Key Constraints:

  • 3 <= m, n <= 50 → The board is small, at most 2,500 cells. Even O(m^2 * n^2) per iteration would be fast enough. Efficiency isn't a concern here, clarity and correctness are.
  • 1 <= board[i][j] <= 2000 → Candy values are always positive. This means we can use negative values as markers without conflicting with actual candy types.

Approach 1: Simulation with Boolean Marking

Intuition

Use a separate boolean matrix to track which cells need to be crushed. Scan every cell to see if it's part of a horizontal or vertical run of three or more identical candies. Mark all such cells in the boolean matrix, crush them (set to 0), apply gravity, and repeat. This directly models the game loop: find matches, remove them, drop, check again.

A separate matrix keeps marking and reading cleanly apart: the scan only ever reads candy values from board, and only ever writes marks to crush, so no marking decision can corrupt a later comparison in the same pass.

Algorithm

  1. Create a boolean matrix crush of the same size as the board, initialized to all false.
  2. Scan every row for windows of three equal non-zero values and mark all three cells as true in crush. Do the same for every column. Overlapping windows extend the marks, so a run of four or more is fully covered.
  3. For every cell marked true, set board[i][j] = 0.
  4. Apply gravity: for each column, scan from the bottom with a write cursor, copy each non-zero value down to the cursor, then fill everything above the cursor with zeroes.
  5. If step 2 marked at least one cell, repeat from step 1. Otherwise the board is stable, so return it.

Visualization and Code

Loading animation...

This approach allocates a fresh boolean matrix every iteration. Candy values are always positive, so the next approach drops the extra matrix and encodes the mark in the sign of each cell instead.

Approach 2: In-Place Simulation with Negation

Intuition

All candy values are positive integers, so negating a value marks it for crushing while abs() still recovers the candy type. The board itself carries the marks, and the separate boolean matrix disappears.

The loop keeps the same shape (mark, crush, drop), with two changes. The marking phase compares absolute values and flips matched cells to negative. The crush and drop phases then merge into a single pass per column that keeps only the positive values and zero-fills the rest, so marked cells never need to be reset to zero explicitly; gravity treats anything non-positive as empty.

Algorithm

  1. Scan every row: if abs(board[i][j]) == abs(board[i][j+1]) == abs(board[i][j+2]) and the value is non-zero, set all three cells to the negated value. Re-negating an already-marked cell writes the same value, so overlapping windows are harmless.
  2. Scan every column with the same logic on board[i][j], board[i+1][j], board[i+2][j].
  3. Crush and drop in one pass: for each column, scan from the bottom with a write cursor, copy each positive value down to the cursor, then fill everything above the cursor with zeroes. Negative (marked) and zero cells are overwritten.
  4. If steps 1-2 negated at least one cell, repeat from step 1. Otherwise the board is stable, so return it.

Visualization and Code

Loading animation...