Skip to content
AI360Xpert
Beta
Difficulty: Hard2-D Dynamic Programming

Longest Increasing Path in a Matrix

Problem in Plain English

Given an integer grid, find the length of the longest path that moves up, down, left, or right to strictly larger values. Every cell alone counts as a path of length 1.

Problem Statement

Given an m×nm \times n integer grid matrix, return the length of the longest strictly increasing path in it.

From each cell you may move to any of the four orthogonal neighbours (never diagonally and never outside the grid) whose value is strictly greater than the current cell. For matrix = [[9,9,4],[6,6,8],[2,1,1]] the answer is 4 via the trail [1, 2, 6, 9].

Constraints

  • m equals matrix.length, the number of rows.
  • n equals the length of each row; the grid is rectangular.
  • 1≤m,n≤2001 \le m,n \le 200
  • Each cell value is an integer between 00 and 231−12^{31}-1, inclusive.

Examples

Example 1

Input
matrix = [[9,9,4],[6,6,8],[2,1,1]]
Output
4

Coordinates (2,1) → (2,0) → (1,0) → (0,0) give values 1 → 2 → 6 → 9, so four cells form a legal path. Equal adjacent 9s and 1s cannot extend it. Every starting cell has length at most 4, as the dry runs show.

Example 2

Input
matrix = [[3,4,5],[3,2,6],[2,2,1]]
Output
4

One longest path is (0,0) → (0,1) → (0,2) → (1,2), with values 3 → 4 → 5 → 6 and length 4. Another starts at the centre 2. The bottom-left 2 cannot jump diagonally to the centre or cross an equal 2; checking only the global minimum would miss valid best starting points.

Example 3

Input
matrix = [[1]]
Output
1

There are no neighbours, but the starting cell itself counts. The answer is 1 rather than 0.

Example 4

Input
matrix = [[7,7],[7,7]]
Output
1

Every orthogonal neighbour is equal, so no move is strictly increasing. Four available cells do not make a path of length four; each start stops immediately.

Intuition

Treat each cell as a state whose answer is the longest increasing path starting there. Each legal move goes to a larger value, so a path cannot return to a cell and the dependency graph has no cycles. A cell alone contributes one; otherwise its answer is one plus the largest answer among its greater neighbours. In Example 1, the same suffix 6 → 9 is needed by both 2 and 1. Remembering a completed suffix avoids exploring it repeatedly. Count cells, rather than moves: 1 → 2 → 6 → 9 has length 4.

Approaches

Raw Depth-First Search

Solution Details

Reveal Raw Depth-First Search: intuition, complexity, and code

Hints

Hint 1
For a fixed starting cell, what happens after choosing its first greater neighbour?
Hint 2
Strict increases prevent cycles. The best suffix from a cell does not depend on which earlier route reached it.
Hint 3
Store 1 plus the maximum completed greater-neighbour length. Use explicit continuation frames if a path may exceed native recursion limits.

Edge Cases

  • A single cell and an all-equal grid both return 1; equal values never connect.
  • Single-row or single-column inputs allow two directions only. Increasing [0,1,2] has length 3; [2,1,0] also has length 3 by moving backwards.
  • A 200 by 200 snake can use all 40,000 cells. An explicit heap stack handles its depth without adjusting runtime recursion limits.
  • Values 0 and 2147483647 are legal; compare directly rather than subtracting or adding a sentinel to a value.
  • Multiple routes may merge into the same suffix, and disconnected local minima may have different lengths; evaluate every start.

Common Mistakes and Interview Tips

  • Using >= instead of > allows equal-valued cycles and invalid paths.
  • Caching on entry records an unfinished answer. Write memo only after all four directions have contributed.
  • Marking a cell globally visited and skipping it later loses its suffix length; reuse a completed numerical memo value instead.
  • Advancing a frame direction after returning from a child can repeatedly explore that child. Advance before the push and propagate its completed length on pop.
  • Recursive DFS may overflow Python, JavaScript or Java call stacks on a legal 40,000-cell path even when memoization makes the work linear.
  • Returning moves rather than visited cells makes a leaf length 0 instead of 1. Sorting values without retaining neighbour coordinates also admits illegal jumps.
  • Do not claim the unmemoized baseline handles every maximum-size input: its repeated suffix exploration is exponential. Explain the shared-state recurrence before the memoization optimization.

Key Takeaway

When strict progress makes dependencies acyclic, define one answer per state and cache only after its dependencies finish. Memoized DFS then visits each state and its outgoing edges once; explicit continuation frames preserve that recurrence on deep inputs.