Search⌘ K

Longest Increasing Subsequence

Explore the longest increasing subsequence problem and learn how to apply dynamic programming to optimize recursive backtracking solutions. Understand how memoization reduces time complexity from exponential to quadratic, and gain skills to implement efficient LIS algorithms in Java for improved problem-solving.

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 ...