Mediumone-dimensional-dp
Longest Increasing Subsequence
Problem (restated)
Return length of the longest strictly increasing subsequence.
Intuition
Maintain smallest tail of all increasing subsequences of each length; binary search place for each num.
Approaches
Patience sorting (tails)
Tested onlyTime O(n log n)Space O(n)
Idea. tails[len-1] = smallest tail for length len; lower_bound replace or append.
Walkthrough. [10,9,2,5,3,7,101,18] → length 4 (2,3,7,101).
Trade-offs. O(n²) DP is simpler; patience is faster.
Solution
export function lengthOfLIS(nums: number[]): number {
const tails: number[] = [];
for (const x of nums) {
let lo = 0, hi = tails.length;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (tails[mid]! < x) lo = mid + 1;
else hi = mid;
}
if (lo === tails.length) tails.push(x);
else tails[lo] = x;
}
return tails.length;
}
export function lengthOfLIS(nums: number[]): number {
const tails: number[] = [];
for (const x of nums) {
let lo = 0, hi = tails.length;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (tails[mid]! < x) lo = mid + 1;
else hi = mid;
}
if (lo === tails.length) tails.push(x);
else tails[lo] = x;
}
return tails.length;
}
Template connection
1D DP / binary search on answer structure.
Reflection
- Which pattern gave this away within 90 seconds?
- What changed from the standard template?
- What would break the current solution?