Goal
Find the length of the longest increasing subsequence (LIS) using a greedy + binary search method.
Key Idea
Maintain an array minLisTails[] where
minLisTails[i] is the smallest possible last element of any
increasing subsequence of length i + 1.
This structure may not equal an actual LIS, but its length always equals the LIS length.
How We Place Each Number
For each incoming value num (i.e., nums[index]),
we find its replacement position in minLisTails[] — the first index idx
such that minLisTails[idx] ≥ num.
Replacing there keeps the tail for length idx + 1 as small as possible,
maximizing our ability to extend to longer subsequences later.
If no such index exists (the value is larger than all current tails), we append it,
which extends the LIS by one.
Binary Search (Replacement Position)
-
We binary search over
minLisTailsusing pointersleftandright. At each step, inspectminLisTails[mid](the element currently highlighted in blue in the visualization). -
If
minLisTails[mid] < num: move left rightward, since the replacement spot (if it exists) must be aftermid.
💡 If no such spot exists (i.e., the value is greater than all tails), we will append it to extend the LIS. -
If
minLisTails[mid] ≥ num: move right leftward (thismidor an earlier index could be the replacement spot). -
When the search finishes,
leftis the first index satisfyingminLisTails[left] ≥ num— i.e., the replacement position. Ifleft === minLisTails.length, it means that no replacement point can be found and num is the greatest value encountered so far, so we append it to extend the LIS.
Why This Works
By keeping each minLisTails[i] as small as possible, we maximize the ability to
extend subsequences to greater lengths. Replacements do not reduce the length already achieved;
they only improve the “future potential” of increasing thatlength. Appends increase the achieved length by one.
Result
After processing all numbers, minLisTails.length is the length of the LIS.