Search⌘ K
AI Features

Longest Increasing Subsequence

Explore dynamic programming methods to solve the longest increasing subsequence problem in Python. Understand two recursive approaches, optimize them with memoization, and implement efficient algorithms running in O(n²) time using 2D and 1D arrays. Gain insights into adding sentinel values and proper evaluation orders for subproblems.

Longest increasing subsequence problem

Another problem we considered in the previous chapter was computing the length of the longest increasing subsequence of a given array A[1..n]A[1 .. n] of numbers. We developed two different recursive backtracking algorithms for this problem. Both algorithms run in O(2n)O(2^n) time in the worst case; both algorithms can be sped up significantly via dynamic programming.

First recurrence: Is this next?

Our first backtracking algorithm evaluated the function LISbigger(i,j)LISbigger(i, j), which we defined as the length of the longest increasing subsequence of A[j..n]A[ j .. n] in which every element is larger than A[i]A[i]. We derived the following recurrence for this function:

LISbigger(i,j)={ 0 if j>nLISbigger(i,j+1)if A[i]A[j]max{LISbigger(i,j+1)1+LISbigger(j,j+1)}otherwiseLISbigger(i,j)= \begin{cases} & \text{ 0 } \hspace{5.9cm} if\space j>n \\ & LISbigger(i,j+1) \hspace{3.3cm} if\space A[i]\geq A[j] \\ & max\begin{Bmatrix} & LISbigger(i,j+1)\\ & 1+LISbigger(j,j+1)\\ \end{Bmatrix}\hspace{1cm} otherwise \end{cases}

To solve the original problem, we can add a sentinel value A[0]=A[0] = −∞ to the array and compute LISbigger(0,1)LISbigger(0, 1).

Each recursive subproblem is identified by two indices ii and jj so there are only O(n2)O(n^2) ...