Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    ← All patterns

    2-D DP

    Two indices (two strings, a grid, or item and capacity) define the state.

    Reach for it when

    • Compare two sequences (LCS, edit distance)
    • Paths in a grid
    • Knapsack: items and a budget

    Core idea

    dp[i][j] answers the subproblem for prefixes s[:i] and t[:j] (or cell (i, j)). Each cell depends on its neighbors up, left, and up-left, so fill row by row. Rolling arrays reduce space to one or two rows.

    Template · O(m * n) time, O(n) with a rolling row

    def lcs(a, b):
    dp = [[0] * (len(b) + 1) for _ in range(len(a) + 1)]
    for i in range(1, len(a) + 1):
    for j in range(1, len(b) + 1):
    if a[i - 1] == b[j - 1]:
    dp[i][j] = dp[i - 1][j - 1] + 1
    else:
    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
    return dp[-1][-1]

    Common pitfalls

    • Off-by-one between dp indices and string indices
    • 0/1 knapsack in 1-D must iterate capacity downward
    • [[0] * n] * m aliases rows in Python

    Practice · 0 / 12 done