Longest Increasing Subsequence (LIS)

Given an array arr[] of size N, the task is to find the length of the Longest Increasing Subsequence (LIS) i.e., the longest possible subsequence in which the elements of the subsequence are sorted in increasing order.
Longest Increasing Subsequence
Examples: Â Â Â Â Â Â
Input: arr[] = {3, 10, 2, 1, 20}
Output: 3
Explanation: The longest increasing subsequence is 3, 10, 20Input: arr[] = {3, 2}
Output:1
Explanation: The longest increasing subsequences are {3} and {2}Input: arr[] = {50, 3, 10, 7, 40, 80}
Output: 4
Explanation: The longest increasing subsequence is {3, 7, 40, 80}
Longest Increasing Sequence using Recursion:
The problem can be solved based on the following idea:
Let L(i) be the length of the LIS ending at index i such that arr[i] is the last element of the LIS. Then, L(i) can be recursively written as:Â
- L(i) = 1 + max(L(j) ) where 0 < j < i and arr[j] < arr[i]; or
- L(i) = 1, if no such j exists.
Formally, the length of LIS ending at index i, is 1 greater than the maximum of lengths of all LIS ending at some index j such that arr[j] < arr[i] where j < i.
We can see that the above recurrence relation follows the optimal substructure property.
Illustration:
Follow the below illustration for a better understanding:
Consider arr[] = {3, 10, 2, 11}
L(i): Denotes LIS of subarray ending at position ‘i’
![]()
Recursion Tree
Follow the steps mentioned below to implement the above idea:
- Create a recursive function.
- For each recursive call, Iterate from the i = 1 to the current position and do the following:Â
- Find the possible length of the longest increasing subsequence ending at the current position if the previous sequence ended at i.
- Update the maximum possible length accordingly.
- Repeat this for all indices and find the answerÂ
Below is the implementation of the recursive approach:
C++
// A Naive C++ recursive implementation// of LIS problem#include <bits/stdc++.h>using namespace std;Â
// To make use of recursive calls, this// function must return two things:// 1) Length of LIS ending with element// arr[n-1].// We use max_ending_here for this purpose// 2) Overall maximum as the LIS may end// with an element before arr[n-1] max_ref// is used this purpose.// The value of LIS of full array of size// n is stored in *max_ref which is// our final resultint _lis(int arr[], int n, int* max_ref){Â
    // Base case    if (n == 1)        return 1;Â
    // 'max_ending_here' is length of    // LIS ending with arr[n-1]    int res, max_ending_here = 1;Â
    // Recursively get all LIS ending with    // arr[0], arr[1] ... arr[n-2]. If    // arr[i-1] is smaller than arr[n-1],    // and max ending with arr[n-1] needs    // to be updated, then update it    for (int i = 1; i < n; i++) {        res = _lis(arr, i, max_ref);        if (arr[i - 1] < arr[n - 1]            && res + 1 > max_ending_here)            max_ending_here = res + 1;    }Â
    // Compare max_ending_here with the    // overall max. And update the    // overall max if needed    if (*max_ref < max_ending_here)        *max_ref = max_ending_here;Â
    // Return length of LIS ending    // with arr[n-1]    return max_ending_here;}Â
// The wrapper function for _lis()int lis(int arr[], int n){Â
    // The max variable holds the result    int max = 1;Â
    // The function _lis() stores its    // result in max    _lis(arr, n, &max);Â
    // Returns max    return max;}Â
// Driver program to test above functionint main(){Â Â Â Â int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â
    // Function call    cout << "Length of lis is " << lis(arr, n);    return 0;} |
C
// A Naive C recursive implementation// of LIS problem#include <stdio.h>#include <stdlib.h>Â
// To make use of recursive calls, this// function must return two things:// 1) Length of LIS ending with element arr[n-1].// We use max_ending_here for this purpose// 2) Overall maximum as the LIS may end with// an element before arr[n-1] max_ref is// used this purpose.// The value of LIS of full array of size n// is stored in *max_ref which is our final resultint _lis(int arr[], int n, int* max_ref){    // Base case    if (n == 1)        return 1;Â
    // 'max_ending_here' is length of LIS    // ending with arr[n-1]    int res, max_ending_here = 1;Â
    // Recursively get all LIS ending with arr[0],    // arr[1] ... arr[n-2]. If arr[i-1] is smaller    // than arr[n-1], and max ending with arr[n-1]    // needs to be updated, then update it    for (int i = 1; i < n; i++) {        res = _lis(arr, i, max_ref);        if (arr[i - 1] < arr[n - 1]            && res + 1 > max_ending_here)            max_ending_here = res + 1;    }Â
    // Compare max_ending_here with the overall    // max. And update the overall max if needed    if (*max_ref < max_ending_here)        *max_ref = max_ending_here;Â
    // Return length of LIS ending with arr[n-1]    return max_ending_here;}Â
// The wrapper function for _lis()int lis(int arr[], int n){    // The max variable holds the result    int max = 1;Â
    // The function _lis() stores its result in max    _lis(arr, n, &max);Â
    // returns max    return max;}Â
// Driver program to test above functionint main(){Â Â Â Â int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â
    // Function call    printf("Length of lis is %d", lis(arr, n));    return 0;} |
Java
// A Naive Java Program for LIS Implementationimport java.io.*;import java.util.*;Â
class LIS {Â
    // Stores the LIS    static int max_ref;Â
    // To make use of recursive calls, this function must    // return two things: 1) Length of LIS ending with    // element arr[n-1]. We use max_ending_here for this    // purpose 2) Overall maximum as the LIS may end with an    // element before arr[n-1] max_ref is used this purpose.    // The value of LIS of full array of size n is stored in    // *max_ref which is our final result    static int _lis(int arr[], int n)    {        // Base case        if (n == 1)            return 1;Â
        // 'max_ending_here' is length of LIS ending with        // arr[n-1]        int res, max_ending_here = 1;Â
        // Recursively get all LIS ending with arr[0],        // arr[1] ... arr[n-2]. If  arr[i-1] is smaller        // than arr[n-1], and max ending with arr[n-1] needs        // to be updated, then update it        for (int i = 1; i < n; i++) {            res = _lis(arr, i);            if (arr[i - 1] < arr[n - 1]                && res + 1 > max_ending_here)                max_ending_here = res + 1;        }Â
        // Compare max_ending_here with the overall max. And        // update the overall max if needed        if (max_ref < max_ending_here)            max_ref = max_ending_here;Â
        // Return length of LIS ending with arr[n-1]        return max_ending_here;    }Â
    // The wrapper function for _lis()    static int lis(int arr[], int n)    {        // The max variable holds the result        max_ref = 1;Â
        // The function _lis() stores its result in max        _lis(arr, n);Â
        // Returns max        return max_ref;    }Â
    // Driver program to test above functions    public static void main(String args[])    {        int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };        int n = arr.length;Â
        // Function call        System.out.println("Length of lis is "                           + lis(arr, n));    }}// This code is contributed by Rajat Mishra |
Python3
# A naive Python implementation of LIS problemÂ
Â
# Global variable to store the maximumglobal maximumÂ
Â
# To make use of recursive calls, this function must return# two things:# 1) Length of LIS ending with element arr[n-1]. We use# max_ending_here for this purpose# 2) Overall maximum as the LIS may end with an element# before arr[n-1] max_ref is used this purpose.# The value of LIS of full array of size n is stored in# *max_ref which is our final resultdef _lis(arr, n):Â
    # To allow the access of global variable    global maximumÂ
    # Base Case    if n == 1:        return 1Â
    # maxEndingHere is the length of LIS ending with arr[n-1]    maxEndingHere = 1Â
    # Recursively get all LIS ending with    # arr[0], arr[1]..arr[n-2]    # If arr[i-1] is smaller than arr[n-1], and    # max ending with arr[n-1] needs to be updated,    # then update it    for i in range(1, n):        res = _lis(arr, i)        if arr[i-1] < arr[n-1] and res+1 > maxEndingHere:            maxEndingHere = res + 1Â
    # Compare maxEndingHere with overall maximum. And    # update the overall maximum if needed    maximum = max(maximum, maxEndingHere)Â
    return maxEndingHereÂ
Â
def lis(arr):Â
    # To allow the access of global variable    global maximumÂ
    # Length of arr    n = len(arr)Â
    # Maximum variable holds the result    maximum = 1Â
    # The function _lis() stores its result in maximum    _lis(arr, n)    return maximumÂ
Â
# Driver program to test the above functionif __name__ == '__main__':Â Â Â Â arr = [10, 22, 9, 33, 21, 50, 41, 60]Â Â Â Â n = len(arr)Â
    # Function call    print("Length of lis is", lis(arr))Â
# This code is contributed by NIKHIL KUMAR SINGH |
C#
using System;Â
// A Naive C# Program for LIS Implementationclass LIS {Â
    // Stores the LIS    static int max_ref;Â
    // To make use of recursive calls, this function must    // return two things: 1) Length of LIS ending with    // element arr[n-1]. We use max_ending_here for this    // purpose 2) Overall maximum as the LIS may end with an    // element before arr[n-1] max_ref is used this purpose.    // The value of LIS of full array of size n is stored in    // *max_ref which is our final result    static int _lis(int[] arr, int n)    {        // Base case        if (n == 1)            return 1;Â
        // 'max_ending_here' is length of LIS ending with        // arr[n-1]        int res, max_ending_here = 1;Â
        // Recursively get all LIS ending with arr[0],        // arr[1] ... arr[n-2]. If  arr[i-1] is smaller        // than arr[n-1], and max ending with arr[n-1] needs        // to be updated, then update it        for (int i = 1; i < n; i++) {            res = _lis(arr, i);            if (arr[i - 1] < arr[n - 1]                && res + 1 > max_ending_here)                max_ending_here = res + 1;        }Â
        // Compare max_ending_here with the overall max        // and update the overall max if needed        if (max_ref < max_ending_here)            max_ref = max_ending_here;Â
        // Return length of LIS ending with arr[n-1]        return max_ending_here;    }Â
    // The wrapper function for _lis()    static int lis(int[] arr, int n)    {        // The max variable holds the result        max_ref = 1;Â
        // The function _lis() stores its result in max        _lis(arr, n);Â
        // Returns max        return max_ref;    }Â
    // Driver program to test above functions    public static void Main()    {        int[] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };        int n = arr.Length;Â
        // Function call        Console.Write("Length of lis is " + lis(arr, n)                      + "\n");    }} |
Javascript
<script>Â
/* A Naive javascript Program for LIS Implementation */Â
Â
    let max_ref; // stores the LIS     /* To make use of recursive calls, this function must return    two things:    1) Length of LIS ending with element arr[n-1]. We use       max_ending_here for this purpose    2) Overall maximum as the LIS may end with an element       before arr[n-1] max_ref is used this purpose.    The value of LIS of full array of size n is stored in    *max_ref which is our final result */    function _lis(arr,n)    {        // base case         if (n == 1)             return 1;                 // 'max_ending_here' is length of LIS ending with arr[n-1]         let res, max_ending_here = 1;         /* Recursively get all LIS ending with arr[0], arr[1] ...            arr[n-2]. If  arr[i-1] is smaller than arr[n-1], and            max ending with arr[n-1] needs to be updated, then            update it */        for (let i = 1; i < n; i++)        {            res = _lis(arr, i);             if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here)                 max_ending_here = res + 1;         }        // Compare max_ending_here with the overall max. And         // update the overall max if needed        if (max_ref < max_ending_here)             max_ref = max_ending_here;                  // Return length of LIS ending with arr[n-1]         return max_ending_here;     }         // The wrapper function for _lis()     function lis(arr,n)    {        // The max variable holds the result         max_ref = 1;                  // The function _lis() stores its result in max         _lis( arr, n);                 // returns max        return max_ref;    }         // driver program to test above functions     let arr=[10, 22, 9, 33, 21, 50, 41, 60 ]    let n = arr.length;     document.write("Length of lis is "                           + lis(arr, n) + "<br>");         // This code is contributed by avanitrachhadiya2155     </script> |
Length of lis is 5
Time Complexity: O(2n) The time complexity of this recursive approach is exponential as there is a case of overlapping subproblems as explained in the recursive tree diagram above.
Auxiliary Space: O(1). No external space is used for storing values apart from the internal stack space.
Longest Increasing Subsequence using Memoization:
If noticed carefully, we can see that the above recursive solution also follows the overlapping subproblems property i.e., same substructure solved again and again in different recursion call paths. We can avoid this using the memoization approach.
We can see that each state can be uniquely identified using two parameters:
- Current index (denotes the last index of the LIS) and
- Previous index (denotes the ending index of the previous LIS behind which the arr[i] is being concatenated).
Below is the implementation of the above approach.
C++
// C++ code of memoization approach for LIS#include <bits/stdc++.h>using namespace std;Â
// To make use of recursive calls, this// function must return two things:// 1) Length of LIS ending with element// arr[n-1].// We use max_ending_here for this purpose// Overall maximum as the LIS may end with// an element before arr[n-1] max_ref is// used this purpose.// The value of LIS of full array of size// n is stored in *max_ref which is// our final resultint f(int idx, int prev_idx, int n, int a[],      vector<vector<int> >& dp){    if (idx == n) {        return 0;    }Â
    if (dp[idx][prev_idx + 1] != -1) {        return dp[idx][prev_idx + 1];    }Â
    int notTake = 0 + f(idx + 1, prev_idx, n, a, dp);    int take = INT_MIN;    if (prev_idx == -1 || a[idx] > a[prev_idx]) {        take = 1 + f(idx + 1, idx, n, a, dp);    }Â
    return dp[idx][prev_idx + 1] = max(take, notTake);}Â
// Function to find length of// longest increasing subsequenceint longestSubsequence(int n, int a[]){Â Â Â Â vector<vector<int> > dp(n + 1, vector<int>(n + 1, -1));Â Â Â Â return f(0, -1, n, a, dp);}Â
// Driver program to test above functionint main(){Â Â Â Â int a[] = { 3, 10, 2, 1, 20 };Â Â Â Â int n = sizeof(a) / sizeof(a[0]);Â
    // Function call    cout << "Length of lis is " << longestSubsequence(n, a);    return 0;} |
Java
// A Memoization Java Program for LIS ImplementationÂ
import java.lang.*;import java.util.Arrays;Â
class LIS {Â
    // To make use of recursive calls, this function must    // return two things: 1) Length of LIS ending with    // element arr[n-1]. We use max_ending_here for this    // purpose 2) Overall maximum as the LIS may end with an    // element before arr[n-1] max_ref is used this purpose.    // The value of LIS of full array of size n is stored in    // *max_ref which is our final result    static int f(int idx, int prev_idx, int n, int a[],                 int[][] dp)    {        if (idx == n) {            return 0;        }Â
        if (dp[idx][prev_idx + 1] != -1) {            return dp[idx][prev_idx + 1];        }Â
        int notTake = 0 + f(idx + 1, prev_idx, n, a, dp);        int take = Integer.MIN_VALUE;        if (prev_idx == -1 || a[idx] > a[prev_idx]) {            take = 1 + f(idx + 1, idx, n, a, dp);        }Â
        return dp[idx][prev_idx + 1]            = Math.max(take, notTake);    }Â
    // The wrapper function for _lis()    static int lis(int arr[], int n)    {        // The function _lis() stores its result in max        int dp[][] = new int[n + 1][n + 1];        for (int row[] : dp)            Arrays.fill(row, -1);Â
        return f(0, -1, n, arr, dp);    }Â
    // Driver program to test above functions    public static void main(String args[])    {        int a[] = { 3, 10, 2, 1, 20 };        int n = a.length;Â
        // Function call        System.out.println("Length of lis is " + lis(a, n));    }}Â
// This code is contributed by Sanskar. |
Python3
# A Naive Python recursive implementation# of LIS problemÂ
Â
import sysÂ
# To make use of recursive calls, this# function must return two things:# 1) Length of LIS ending with element arr[n-1].#Â Â Â Â We use max_ending_here for this purpose# 2) Overall maximum as the LIS may end with#Â Â Â Â an element before arr[n-1] max_ref is#Â Â Â Â used this purpose.# The value of LIS of full array of size n# is stored in *max_ref which is our final resultÂ
Â
def f(idx, prev_idx, n, a, dp):Â
    if (idx == n):        return 0Â
    if (dp[idx][prev_idx + 1] != -1):        return dp[idx][prev_idx + 1]Â
    notTake = 0 + f(idx + 1, prev_idx, n, a, dp)    take = -sys.maxsize - 1    if (prev_idx == -1 or a[idx] > a[prev_idx]):        take = 1 + f(idx + 1, idx, n, a, dp)Â
    dp[idx][prev_idx + 1] = max(take, notTake)    return dp[idx][prev_idx + 1]Â
# Function to find length of longest increasing# subsequence.Â
Â
def longestSubsequence(n, a):Â
    dp = [[-1 for i in range(n + 1)]for j in range(n + 1)]    return f(0, -1, n, a, dp)Â
Â
# Driver program to test above functionif __name__ == '__main__':Â Â Â Â a = [3, 10, 2, 1, 20]Â Â Â Â n = len(a)Â
    # Function call    print("Length of lis is", longestSubsequence(n, a))Â
# This code is contributed by shinjanpatra |
C#
// C# approach to implementation the memoization approachÂ
using System;Â
class GFG {Â
    // To make use of recursive calls, this    // function must return two things:    // 1) Length of LIS ending with element arr[n-1].    // We use max_ending_here for this purpose    // 2) Overall maximum as the LIS may end with    // an element before arr[n-1] max_ref is    // used this purpose.    // The value of LIS of full array of size n    // is stored in *max_ref which is our final result    public static int INT_MIN = -2147483648;Â
    public static int f(int idx, int prev_idx, int n,                        int[] a, int[, ] dp)    {        if (idx == n) {            return 0;        }        if (dp[idx, prev_idx + 1] != -1) {            return dp[idx, prev_idx + 1];        }        int notTake = 0 + f(idx + 1, prev_idx, n, a, dp);        int take = INT_MIN;        if (prev_idx == -1 || a[idx] > a[prev_idx]) {            take = 1 + f(idx + 1, idx, n, a, dp);        }Â
        return dp[idx, prev_idx + 1]            = Math.Max(take, notTake);    }Â
    // Function to find length of longest increasing    // subsequence.    public static int longestSubsequence(int n, int[] a)    {        int[, ] dp = new int[n + 1, n + 1];Â
        for (int i = 0; i < n + 1; i++) {            for (int j = 0; j < n + 1; j++) {                dp[i, j] = -1;            }        }        return f(0, -1, n, a, dp);    }Â
    // Driver code    static void Main()    {        int[] a = { 3, 10, 2, 1, 20 };        int n = a.Length;        Console.WriteLine("Length of lis is "                          + longestSubsequence(n, a));    }}Â
// The code is contributed by Nidhi goel. |
Javascript
/* A Naive Javascript recursive implementation      of LIS problem */Â
      /* To make use of recursive calls, this      function must return two things:      1) Length of LIS ending with element arr[n-1].          We use max_ending_here for this purpose      2) Overall maximum as the LIS may end with          an element before arr[n-1] max_ref is          used this purpose.      The value of LIS of full array of size n      is stored in *max_ref which is our final result      */Â
      function f(idx, prev_idx, n, a, dp) {        if (idx == n) {          return 0;        }Â
        if (dp[idx][prev_idx + 1] != -1) {          return dp[idx][prev_idx + 1];        }Â
        var notTake = 0 + f(idx + 1, prev_idx, n, a, dp);        var take = Number.MIN_VALUE;        if (prev_idx == -1 || a[idx] > a[prev_idx]) {          take = 1 + f(idx + 1, idx, n, a, dp);        }Â
        return (dp[idx][prev_idx + 1] = Math.max(take, notTake));      }      // Function to find length of longest increasing      // subsequence.      function longestSubsequence(n, a) {        var dp = Array(n + 1)          .fill()          .map(() => Array(n + 1).fill(-1));        return f(0, -1, n, a, dp);      }Â
      /* Driver program to test above function */Â
      var a = [3, 10, 2, 1, 20];      var n = 5;      console.log("Length of lis is " + longestSubsequence(n, a));             // This code is contributed by satwiksuman. |
Length of lis is 3
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Longest Increasing Subsequence using Dynamic Programming:
Due to optimal substructure and overlapping subproblem property, we can also utilise Dynamic programming to solve the problem. Instead of memoization, we can use the nested loop to implement the recursive relation.
The outer loop will run from i = 1 to N and the inner loop will run from j = 0 to i and use the recurrence relation to solve the problem.
Below is the implementation of the above approach:Â Â
C++
// Dynamic Programming C++ implementation// of LIS problem#include <bits/stdc++.h>using namespace std;Â
// lis() returns the length of the longest// increasing subsequence in arr[] of size nint lis(int arr[], int n){Â Â Â Â int lis[n];Â
    lis[0] = 1;Â
    // Compute optimized LIS values in    // bottom up manner    for (int i = 1; i < n; i++) {        lis[i] = 1;        for (int j = 0; j < i; j++)            if (arr[i] > arr[j] && lis[i] < lis[j] + 1)                lis[i] = lis[j] + 1;    }Â
    // Return maximum value in lis[]    return *max_element(lis, lis + n);}Â
// Driver program to test above functionint main(){Â Â Â Â int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â
    // Function call    printf("Length of lis is %d\n", lis(arr, n));    return 0;} |
Java
// Dynamic Programming Java implementation// of LIS problemÂ
import java.lang.*;Â
class LIS {Â
    // lis() returns the length of the longest    // increasing subsequence in arr[] of size n    static int lis(int arr[], int n)    {        int lis[] = new int[n];        int i, j, max = 0;Â
        // Initialize LIS values for all indexes        for (i = 0; i < n; i++)            lis[i] = 1;Â
        // Compute optimized LIS values in        // bottom up manner        for (i = 1; i < n; i++)            for (j = 0; j < i; j++)                if (arr[i] > arr[j] && lis[i] < lis[j] + 1)                    lis[i] = lis[j] + 1;Â
        // Pick maximum of all LIS values        for (i = 0; i < n; i++)            if (max < lis[i])                max = lis[i];Â
        return max;    }Â
    // Driver code    public static void main(String args[])    {        int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };        int n = arr.length;Â
        // Function call        System.out.println("Length of lis is "                           + lis(arr, n));    }}Â
// This code is contributed by Rajat Mishra |
Python3
# Dynamic programming Python implementation# of LIS problemÂ
Â
# lis returns length of the longest# increasing subsequence in arr of size ndef lis(arr):Â Â Â Â n = len(arr)Â
    # Declare the list (array) for LIS and    # initialize LIS values for all indexes    lis = [1]*nÂ
    # Compute optimized LIS values in bottom up manner    for i in range(1, n):        for j in range(0, i):            if arr[i] > arr[j] and lis[i] < lis[j] + 1:                lis[i] = lis[j]+1Â
    # Initialize maximum to 0 to get    # the maximum of all LIS    maximum = 0Â
    # Pick maximum of all LIS values    for i in range(n):        maximum = max(maximum, lis[i])Â
    return maximumÂ
Â
# Driver program to test above functionif __name__ == '__main__':Â Â Â Â arr = [10, 22, 9, 33, 21, 50, 41, 60]Â Â Â Â print("Length of lis is", lis(arr))Â
Â
# This code is contributed by Nikhil Kumar Singh |
C#
// Dynamic Programming C# implementation of LIS problemÂ
using System;class LIS {Â
    // lis() returns the length of the longest increasing    // subsequence in arr[] of size n    static int lis(int[] arr, int n)    {        int[] lis = new int[n];        int i, j, max = 0;Â
        // Initialize LIS values for all indexes        for (i = 0; i < n; i++)            lis[i] = 1;Â
        // Compute optimized LIS values in bottom up manner        for (i = 1; i < n; i++)            for (j = 0; j < i; j++)                if (arr[i] > arr[j] && lis[i] < lis[j] + 1)                    lis[i] = lis[j] + 1;Â
        // Pick maximum of all LIS values        for (i = 0; i < n; i++)            if (max < lis[i])                max = lis[i];Â
        return max;    }Â
    // Driver code    public static void Main()    {        int[] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };        int n = arr.Length;Â
        // Function call        Console.WriteLine("Length of lis is "                          + lis(arr, n));    }}Â
// This code is contributed by Ryuga |
Javascript
<script>Â
// Dynamic Programming Javascript implementation// of LIS problem   // lis() returns the length of the longest// increasing subsequence in arr[] of size nfunction lis(arr, n){    let lis = Array(n).fill(0);    let i, j, max = 0;Â
    // Initialize LIS values for all indexes    for(i = 0; i < n; i++)        lis[i] = 1;Â
    // Compute optimized LIS values in    // bottom up manner     for(i = 1; i < n; i++)        for(j = 0; j < i; j++)            if (arr[i] > arr[j] && lis[i] < lis[j] + 1)                lis[i] = lis[j] + 1;Â
    // Pick maximum of all LIS values     for(i = 0; i < n; i++)        if (max < lis[i])            max = lis[i];Â
    return max;}Â
// Driver codelet arr = [ 10, 22, 9, 33, 21, 50, 41, 60 ];let n = arr.length;document.write("Length of lis is " + lis(arr, n) + "\n");Â
// This code is contributed by avijitmondal1998Â
</script> |
Length of lis is 5
Time Complexity: O(N2) As a nested loop is used.
Auxiliary Space: O(N) Use of any array to store LIS values at each index.
Note: The time complexity of the above Dynamic Programming (DP) solution is O(n^2), but there is an O(N* logN) solution for the LIS problem. We have not discussed the O(N log N) solution here.
Refer: Longest Increasing Subsequence Size (N * logN) for the mentioned approach.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



