CodeGround
DashboardProblemsInterviewsAssessmentsCourses
CodeGround
DashboardProblemsInterviewsAssessmentsCourses
The Technical Interview Course

0 of 170 lessons complete

  • Choose, explore, undo
  • What the start index controls
  • When order matters
  • Duplicates in the input
  • When the branching factor comes from the data
  • Pruning: never build what cannot work
  • Choosing where to cut
  • Backtracking on a grid
  • Several constraints at once
  • Retrieval: the four decisions

Backtracking

101 / 170

Backtracking/Lesson 8 of 10·About 48 min

Backtracking on a grid

Mark a cell as occupied, explore the neighbors, unmark it. The unmark is what makes it a search rather than a flood fill.

Key idea

The choice is a direction

On a grid, each level of the search steps to a neighboring cell. The four directions are the branches, and the cell being stood on has to be marked so the path does not immediately walk back over itself.

The mark is temporary. When the search returns from a cell, that cell becomes available again for other paths, which is exactly the undo step.

1def count_paths(grid, start_row, start_col, length):2    """Paths of the given length that never revisit a cell."""3    rows, cols = len(grid), len(grid[0])4    found = 05 6    def explore(row, col, remaining):7        nonlocal found8        if remaining == 0:9            found += 110            return11        original = grid[row][col]12        grid[row][col] = "#"                       # mark13        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):14            r, c = row + dr, col + dc15            if 0 <= r < rows and 0 <= c < cols and grid[r][c] != "#":16                explore(r, c, remaining - 1)17        grid[row][col] = original                  # unmark18 19    explore(start_row, start_col, length)20    return found21 22board = [["a", "b"], ["c", "d"]]23print(count_paths(board, 0, 0, 2))24print(board)

Why it works

Restore the original, not a blank

The cell's previous contents are saved before marking and put back after. Writing a fixed value back instead would destroy the board.

The final print exists to check exactly that: after the search completes, the grid is identical to what was passed in. Any search that mutates its input should leave it as it found it, and printing the input afterward is a cheap way to verify it.

Tip

A separate visited set is the alternative

Instead of writing into the grid you can keep a set of occupied coordinates, adding before the recursion and discarding after. It does not touch the input at all, which is safer when the caller might still need it.

It costs a hash operation per step rather than an array write. Both are standard; mutating the grid is faster and marginally ruder.

Key idea

Why the unmark makes this different from a flood fill

Unit 12 will use almost identical code to explore connected regions, and in that setting cells are marked visited and never unmarked, because visiting a cell once is enough to know it belongs to the region.

Here every distinct path matters, so a cell used by one path must be free for another. That single difference, whether the mark is permanent or undone, is what separates a traversal from a search.

It is also the difference in cost. A traversal touches each cell once and is linear. This search can visit a cell once per path through it, and is exponential.

Edge cases

Searching from every start

When a problem does not say where to begin, the search runs from every cell, which multiplies the cost by the number of cells. Pruning matters much more as a result.

The cheapest prune is to refuse a start whose cell cannot possibly begin a valid path. Checking the first character before descending costs nothing and removes most starting positions immediately.

Complexity· 5 min

Cost of a grid search

Searching for a path of length L from every cell of an m by n grid, with four directions available at each step. Give the time complexity in terms of the cell count and L, and the extra space beyond the grid.

Python
1for row in range(rows):2    for col in range(cols):3        if explore(row, col, 0):4            return True
Time
Extra space
Problem· 30 min

Word Search

Read the constraints first and let them tell you what complexity is expected. Derive the approach, implement it, run the tests, and submit when it passes.

PreviousChoosing where to cut
NextSeveral constraints at once

0 of 3 parts complete