Grid optimization, 0/1 knapsack, and dual string alignments
562 problems·13 Easy·280 Medium·269 Hard
Pattern Study Guide & Cheat Sheet· O(m * n) quadratic cell visits · O(m * n) table, reducible to O(min(m, n)) rolling row
▼
Solve problems with two independent dimensions (e.g. two strings, grid cells, or items vs capacity) by filling an M × N table where dp[i][j] transitions from adjacent predecessors.
Core Invariant: Table grid invariant: Every cell `dp[i][j]` is derived from `dp[i-1][j]` (delete/skip first), `dp[i][j-1]` (insert/skip second), or `dp[i-1][j-1]` (match/replace both). Base row `i=0` and col `j=0` define boundary conditions.
Recognize it (Keywords & Signals)
Compare two strings: Longest Common Subsequence, Edit Distance
Greedy works (e.g. Fractional Knapsack), or dimensions are sparse with massive bounds (use memoized recursion).
How to solve (Step-by-step)
1.Define `dp[i][j]`: e.g. LCS length of `text1[0..i-1]` and `text2[0..j-1]`.
2.Create table: `dp = [[0] * (n + 1) for _ in range(m + 1)]`.
3.Initialize base cases (row 0 and column 0).
4.Fill row by row: if characters match `text1[i-1] == text2[j-1]`, take diagonal `dp[i-1][j-1] + 1`; else take `max(dp[i-1][j], dp[i][j-1])`.
5.Return bottom-right cell `dp[m][n]`.
Watch for (Interview Traps)
Python list multiplication bug: `[[0] * n] * m` makes shallow copies of rows! Always use comprehension `[[0] * n for _ in range(m)]`
Mismatch between 1-based DP table indices `i, j` and 0-based string characters `s[i-1]`
Rolling array for Knapsack requires iterating capacity backwards to prevent reusing the same item
2D DP on Two Strings (Longest Common Subsequence)
def longest_common_subsequence(text1: str, text2: str) -> int:
m, n = len(text1), len(text2)
# dp[i][j] = LCS length between text1[:i] and text2[:j]
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if text1[i - 1] == text2[j - 1]:
# Characters match: extend diagonal subsequence
dp[i][j] = 1 + dp[i - 1][j - 1]
else:
# Discard either char from text1 or text2
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[m][n]
Cost
O(m * n) quadratic cell visits · O(m * n) table, reducible to O(min(m, n)) rolling row (Can compress to 1D rolling array if only previous row is needed.)
Canonical problems
#1143 Longest Common Subsequence:Archetypal string comparison 2D table
What is the 2D Dynamic Programming & Knapsack pattern in coding interviews?
Grid optimization, 0/1 knapsack, and dual string alignments It is categorized under Advanced & DP and features 562 curated interview problems across Easy (13), Medium (280), and Hard (269) difficulties.
Which tech companies frequently test 2D Dynamic Programming & Knapsack?
How do I master the 2D Dynamic Programming & Knapsack pattern?
Start by studying the algorithmic strategy and template code, then practice Easy and Medium problems before attempting Hard problems under timed conditions.