Longest Increasing Subsequence
Length of the longest strictly increasing subsequence (elements keep order, need not be adjacent).
Open on LeetCode ↗Intuition
Classic DP: dp[i] = length of the best increasing subsequence ending at i, built by scanning all smaller earlier elements. The O(n log n) upgrade keeps a list tails where tails[k] is the smallest possible tail of an increasing subsequence of length k+1 — each new number either extends the list or improves (lowers) one tail via binary search.
Approach
O(n²) DP first
dp[i] = 1 + max(dp[j]) over all j < i with nums[j] < nums[i]. Answer is max(dp). Simple, and the base for many follow-up problems.
The tails insight
Among all increasing subsequences of length L, only the one with the smallest tail matters — it is the easiest to extend. So keep just that smallest tail per length: tails is sorted, enabling binary search.
Patience step
For each num: find the first tail ≥ num (bisect_left). If none, num extends the longest run (append). Otherwise it replaces that tail — same length, better (smaller) tail. Length of tails is the answer.
Solution & live demo
Edge cases
Every number replaces tails[0]; answer 1.
bisect_left makes equal values replace, not extend — enforcing strict increase.
Only its length is meaningful; elements may come from different subsequences.