Longest increasing subsequence
ID: longest-increasing-subsequence
A longest increasing subsequence is an increasing subsequence of maximum length. Write that length as , with for the empty sequence; a nonempty input has . Several selections can attain the same maximum. Here uses the weak convention ; write for the maximum length of a strictly increasing subsequence. For , these lengths are three and one respectively; for an input with distinct values they agree.
For , the answer is , attained at indices , while . One useful interpretation is the smallest number of deletions needed to make the surviving sequence nondecreasing:Indeed, keeping a longest increasing subsequence attains this bound, and any valid remaining sequence is an increasing subsequence, so cannot have more than terms. In this example the answer is . This makes a measure of how much order can be recovered without moving any observation.
A table that ends at each position. Let be the maximum length of an increasing subsequence ending specifically at position . The dynamic programming recurrence relation isThe zero covers a selection consisting only of . Otherwise its penultimate index is an eligible ; append to an optimal selection ending there. Fill entries in increasing index order. For strictly increasing subsequences, change the comparison to . The strict version and reconstruction are developed in University of Toronto, CSC373 tutorial 4 solutions (2018), exercise 2; the weak version follows by allowing equality at the append step.
In the worked input, the weak table is and the strict table is . At the second , equality extends the first in the weak table. The final entry is only one, although the optimum is four: the best increasing subsequence need not finish at the last input position. Record a maximizing predecessor whenever . Following these stored indices from any position maximizing , then reversing them, gives an actual longest increasing subsequence. For the weak example the backward chain is .
Skipping positions and allowing equal values changes the optimum
. An original toy input, not measured data. The colored selection keeps indices and values . The two dynamic programming rows give the best lengths ending at every position; the backward arrows reconstruct the weak longest increasing subsequence. Details.Scanning all earlier positions for each uses time complexity and space complexity for lengths and predecessors, using Big O notation and assuming constant-time comparisons and operations on indices.
Keep the easiest ending to extend. The faster algorithm maintains a minimum-tail table for increasing subsequences: is the smallest final value of any length- increasing subsequence in the processed prefix. For equal lengths, a smaller ending permits every future extension allowed by a larger ending. Thus only one best ending per length is needed. The table is nondecreasing, since removing the last term of a length- selection gives . Start with an empty table. On reading , use binary search to find the first entry strictly greater than : replace it by , or append if there is no such entry. Its position is one beyond the longest existing length whose ending is at most . See Liben-Nowell, Vee and Zhu, section 3.1 and Figure 1.
Duplicates determine the binary search rule: weak increase replaces the first , whereas strict increase replaces the first . In Python these positions are returned by
bisect_right(T, v) and bisect_left(T, v) respectively, counting positions from zero. Replace an entry or append; do not insert and shift the remaining entries. The documented equality rules are in Python documentation, bisect_left and bisect_right. Each search takes comparisons, giving time complexity , conventionally for , and space complexity for the weak length alone.Two binary-search tie rules give different minimum-tail tables
. Original exact traces for the same toy input, not measured data. Each cell shows a tail value and the input index supplying it; the outlined cell was updated in that row. At the second , the weak algorithm appends and the strict algorithm replaces. The final weak table has length four, but its supplier indices are not in increasing order. Details.A length certificate needs separate reconstruction. The final weak tail values are , but they do not form an increasing subsequence of this input: the zero occurs last. Each table entry certifies a selection of its own length; the entries need not come from one compatible selection. To recover a longest increasing subsequence during the fast algorithm, store a supplier index for each tail and a predecessor index for each input position. Before replacing slot , save , or no predecessor if , then set . Later replacements leave saved unchanged. Follow predecessors from the final and reverse. This uses space complexity and returns indices for the weak trace. The same construction works with the strict comparator; compare the two auxiliary arrays in CP Algorithms contributors, restoring the subsequence after binary search.
Deleting or changing one term. If deletes position , thenDeleting cannot create a longer increasing subsequence; removing position from a previously optimal selection loses at most one term. If instead changes just the value at position , both inputs have the same deleted sequence, so their lengths each lie between its length and its length plus one. Consequently . These bounds also hold for strictly increasing subsequences. In the weak example, deleting either lowers the length to three, while deleting the final zero leaves it four. This is a Lipschitz bound for single-term edits, regardless of the numerical size of a replacement. Insertion has the same bound by reversing deletion, so insertions, deletions or replacements can change by at most .
For historical context, [ref]
https://doi.org/10.1016/0012-365X(75)90103-X. Fredman, On computing the length of longest increasing subsequences (1975)
studies the comparison count for distinct elements of a totally ordered set. Its distinctness assumption makes the weak and strict conventions coincide. No distinctness assumption is needed for the comparator-specific algorithms above.The Longest Increasing Subsequence (LIS) is a well-known problem in computer science and mathematics that involves finding the longest subsequence of a given sequence of numbers where the elements of the subsequence are in strictly increasing order. A subsequence is a sequence derived from another sequence by deleting some elements without changing the order of the remaining elements.
New to topics? Read the docs here!

