Longest Increasing Subsequence
mediumTests passed 2026-11-11v1.0.01. Core Invariant / The Trick
Patience sorting (`tails` invariant): maintain `tails[k]` = smallest possible tail value of any strictly increasing subsequence of length `k + 1`. Because `tails` stays strictly sorted, replace the first element `>= x` via `bisect_left` (or append when `x` exceeds all tails).
2. Complexity Bounds & Proof
Replacing a larger tail with a smaller `x` never shrinks reachable length while making future extensions strictly easier; `N` binary searches take `O(N log N)`.
3. Minimal Idiomatic Code
def lengthOfLIS(nums: list[int]) -> int:
tails = []
for x in nums:
idx = bisect.bisect_left(tails, x)
if idx == len(tails):
tails.append(x)
else:
tails[idx] = x
return len(tails)4. Failure Modes & Interview Follow-ups
Pitfalls:- Note `tails` holds valid lengths, NOT necessarily an actual valid subsequence path (remember if asked to reconstruct, store predecessor indices alongside `tails`).
- Strict increasing uses lower-bound (`bisect_left`); non-decreasing uses upper-bound (`bisect_right`).
Follow-ups:- Russian Doll Envelopes: sort widths ascending and heights **descending**, then compute 1D LIS on heights.
Personal Notes & Scratchpad (Local-First Yjs CRDT)
Saved instantaneously in IndexedDB. Streams live across peers via Hocuspocus when signed in.
Related Invariants
Browser Scratchpad
Console Output
Click Run or press Cmd/Ctrl+Enter to execute locally in a Web Worker.