Longest Common Subsequence
Recognize the pattern
Brute force idea
A straightforward first read of Longest Common Subsequence is this: Generate all subsequences of both strings and find the longest common one. Exponential. That instinct is useful because it follows the prompt literally, but it usually keeps revisiting work the problem is begging you to organize.
Better approach
A calmer way to see Longest Common Subsequence is this: 2D DP: dp[i][j] = LCS length of s1[0.i-1] and s2[0.j-1]. If s1[i-1] == s2[j-1], dp[i][j] = dp[i-1][j-1] + 1. Otherwise, dp[i][j] = max(dp[i-1][j], dp[i][j-1]). The goal is not to be clever for its own sake, but to remember the one relationship that keeps the solution grounded as you move forward.
Key invariant
The compass for Longest Common Subsequence is this: When characters match, both are part of the LCS — extend from dp[i-1][j-1]. When they don't, the LCS either skips s1[i-1] or s2[j-1] — take the longer option. As long as that statement keeps holding, you can trust the steps built on top of it.
Watch out for
A common way to get lost in Longest Common Subsequence is this: Confusing longest common SUBSEQUENCE with longest common SUBSTRING — subsequences don't need to be contiguous. When characters don't match, you take max, not reset to 0. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.