Open In App

Longest Common Increasing Subsequence (LCS + LIS)

Last Updated : 05 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two arrays, a[] and b[], find the length of the longest common increasing subsequence(LCIS). LCIS refers to a subsequence that is present in both arrays and strictly increases.
Prerequisites: LCS, LIS.

Examples:

Input: a[] = [3, 4, 9, 1], b[] = [5, 3, 8, 9, 10, 2, 1]
Output: 2
Explanation: The longest increasing subsequence that is common is {3, 9} and its length is 2.

Input: a[] = [1, 1, 4, 3], b[] = [1, 1, 3, 4]
Output: 2
Explanation: There are two common subsequences {1, 4} and {1, 3} both of length 2.

Using Recursion - O(2^(m+n)) Time and O(m+n) Space

We can identify a recursive pattern in this problem. There are three state variables: i index for array a[], j index for array b[] and prevIndex index of the previous element that we included from array a[].

We consider two cases for recursion:

  • If the element satisfies the following conditions, we include it in the subsequence and move on to the next element in both a[] and b[]
    1. prevIndex is equal to -1 or a[prevIndex] is greater than a[i].
    2. a[i] is equal to b[j].
  • We iterate to next element in either a or b.

Recurrence relation:

if (a[i] == b[j] and (prevIndex == -1 or a[i] < a[prevIndex]))

  • LCIS(i, j, prevIndex) = 1 + LCIS(i-1, j-1, i)

otherwise

  • LCIS(i, j, prevIndex) = max(LCIS(i-1, j, prevIndex), LCIS(i, j-1, prevIndex))

Base Case: If either array is completely traversed i.e. if (i < 0 || j < 0) return 0

C++
// A C++ Program to find length of the Longest Common
// Increasing Subsequence (LCIS)

#include <bits/stdc++.h>
using namespace std;

// Recursive function to find the length of the
//Longest Common Increasing Subsequence
int findLCIS(int i, int j, int prevIndex,
             vector<int> &a, vector<int> &b){
  
    // Base case: If either array is completely
    //traversed, return 0
  
    if (i < 0 || j < 0)
        return 0;

    int include = 0;
    int exclude = 0;

    // If the current elements are equal and 
  	// maintain the increasing property
    if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])){
      
        // Include the current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b); 
    }

    // Explore the subsequences by skipping 
   //an element in either of the arrays
    exclude = max(findLCIS(i - 1, j, prevIndex, a, b), 
                       findLCIS(i, j - 1, prevIndex, a, b));

    // Return the maximum of including or
  	// excluding the current element
    return max(include, exclude);
}

int LCIS(vector<int> &a, vector<int> &b){
    int m = a.size();
    int n = b.size();
    return findLCIS(m - 1, n - 1, -1, a, b);
}

int main(){
    vector<int> a = {3, 4, 9, 1};
    vector<int> b = {5, 3, 8, 9, 10, 2, 1};

    cout <<LCIS(a, b);
    return (0);
}
Java
// A Java Program to find length of the Longest
// Common Increasing Subsequence (LCIS)
import java.io.*;

class GfG {

    static int findLCIS(int i, int j, int prevIndex,
                                int[] a, int[] b){
      
        // Base case: If either array is fully traversed
        if (i < 0 || j < 0)
            return 0;

        int include = 0;
        int exclude = 0;

        // If current elements are equal and satisfy the
        // increasing condition
        if (a[i] == b[j]
            && (prevIndex == -1 || a[i] < a[prevIndex])) {
          
          // Include the current element
            include = 1 + findLCIS(
                          i - 1, j - 1, i, a,
                          b); 
        }

        // Explore skipping an element from either array
        exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b),
                       findLCIS(i, j - 1, prevIndex, a, b));

        // Return the maximum of including or excluding the
        // current element
        return Math.max(include, exclude);
    }
    static int LCIS(int[] a, int[] b){
      
        return findLCIS(a.length - 1, b.length - 1, -1, a,
                        b);
    }

    public static void main(String[] args){
        int a[] = { 3, 4, 9, 1 };
        int b[] = { 5, 3, 8, 9, 10, 2, 1 };

        System.out.println(LCIS(a, b));
    }
}
Python
# Python Program to find length of the 
# Longest Common Increasing Subsequence (LCIS)

def findLCIS(i, j, prevIndex, a, b):
  
        # Base case: If either array is fully traversed
        if i < 0 or j < 0:
            return 0
        
        include = 0
        exclude = 0
        
        # If current elements are equal and
        # satisfy the increasing condition
        if a[i] == b[j] and (prevIndex == -1 or a[i] < a[prevIndex]):
           
            # Include the current element
            include = 1 + findLCIS(i - 1, j - 1, i, a, b)  
        
        # Explore skipping an element from either array
        exclude = max(findLCIS(i - 1, j, prevIndex, a, b), 
                      findLCIS(i, j - 1, prevIndex, a, b))
        
        # Return the maximum of including or 
        #excluding the current element
        return max(include, exclude)

def LCIS(a, b):
       
        # Start recursion from the last indices with no previous element
        return findLCIS(len(a) - 1, len(b) - 1, -1, a, b)

if __name__ == "__main__":
    
    a = [3, 4, 9, 1]
    b = [5, 3, 8, 9, 10, 2, 1]

    print(LCIS(a, b))
C#
// A C# Program to find length of the Longest
// Common Increasing Subsequence (LCIS)
using System;

class GfG {

    // Recursive function to find the LCIS
    static int FindLCIS(int i, int j, int prevIndex,
                        int[] a, int[] b) {
      
        // Base case: If either array is fully traversed
        if (i < 0 || j < 0) {
            return 0;
        }

        int include = 0;
        int exclude = 0;

        // If current elements are equal and satisfy the
        // increasing condition
        if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])) {
          
           // Include the current element
            include
                = 1
                  + FindLCIS(i - 1, j - 1, i, a, b);
        }

        // Explore skipping an element from either array
        exclude = Math.Max(
            FindLCIS(i - 1, j, prevIndex, a, b),
            FindLCIS(i, j - 1, prevIndex, a, b));

        // Return the maximum of including or excluding the
        // current element
        return Math.Max(include, exclude);
    }

    static int LCIS(int[] a, int[] b) {
      
        // Start recursion from the last indices with no
        // previous element
        return FindLCIS(a.Length - 1, b.Length - 1,
                        -1, a, b);
    }

    static void Main() {
      
        int[] a = { 3, 4, 9, 1 };
        int[] b = { 5, 3, 8, 9, 10, 2, 1 };

        Console.Write(LCIS(a, b));
    }
}
JavaScript
// Javascript Program to find length of the Longest
// Common Increasing Subsequence (LCIS)

function findLCIS(i, j, prevIndex, a, b){

    // Base case: If either array is fully traversed
    if (i < 0 || j < 0) {
        return 0;
    }

    let include = 0;
    let exclude = 0;

    // If current elements are equal and satisfy the
    // increasing condition
    if (a[i] === b[j]
        && (prevIndex === -1
            || a[i] < a[prevIndex])) {

        // Include the current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b);
    }

    // Explore skipping an element from either array
    exclude = Math.max(
        findLCIS(i - 1, j, prevIndex, a, b),
        findLCIS(i, j - 1, prevIndex, a, b));

    // Return the maximum of including or excluding the
    // current element
    return Math.max(include, exclude);
}

function LCIS(a, b){

    // Start recursion from the last indices with no
    // previous element
    return findLCIS(a.length - 1, b.length - 1, -1,
                    a, b);
}

let a = [ 3, 4, 9, 1 ];
let b = [ 5, 3, 8, 9, 10, 2, 1 ];

console.log(LCIS(a, b));

Output
2

Using Top-Down DP (Memoization) - O(m*n*m) Time and O(m*n*m) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: Maximum subsequence length for a given i, j and prevIndex , i.e., LCIS(i, j, prevIndex), depends on the optimal solutions of the subproblems LCIS(i-1, j, prevIndex), LCIS(i, j-1, prevIndex) and LCIS(i-1, j-1, i). By choosing the maximum of these optimal substructures, we can efficiently calculate the maximum subsequence length.

2. Overlapping Subproblems: While applying a recursive approach in this problem, we notice that certain subproblems are computed multiple times.

  • There are three parameter that change in the recursive solution: i going from 0 to m-1, j going from 0 to n-1 and prevIndex going from 0 to m-1. So we create a 3D array of size m*n*m for memoization.
  • We initialize this array as -1 to indicate nothing is computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
C++
// A C++ program to find length of the Longest Common
// Increasing Subsequence (LCIS) using memoization

#include <bits/stdc++.h>

using namespace std;

// Recursive function with memoization to find LCIS
int findLCIS(int i, int j, int prevIndex, vector<int> &a,
             vector<int> &b, vector<vector<vector<int>>> &memo){

    // Base case: If either array is fully traversed
    if (i < 0 || j < 0)
        return 0;

    // If the result has already been computed, return it
    if (memo[i][j][prevIndex + 1] != -1)
        return memo[i][j][prevIndex + 1];

    int include = 0;
    int exclude = 0;

    // If the current elements match and satisfy 
  	// the increasing condition
    if (a[i] == b[j] && 
        (prevIndex == -1 || a[i] < a[prevIndex])) {

        // Include the current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b, memo);
    }

    // Explore excluding the current element from either array
    exclude =
        max(findLCIS(i - 1, j, prevIndex, a, b, memo), 
            findLCIS(i, j - 1, prevIndex, a, b, memo));

    // Store the result in the memo table and return it
    memo[i][j][prevIndex + 1] = max(include, exclude);
    return memo[i][j][prevIndex + 1];
}

// Function to initialize the memo table 
// and start the recursion
int LCIS(vector<int> &a, vector<int> &b) {
    int m = a.size();
    int n = b.size();

    // Initialize the memoization table 
   // with -1 (indicating uncomputed states)
    vector<vector<vector<int>>> memo(m, 
	vector<vector<int>>(n, vector<int>(m + 1, -1)));

    // Start recursion from the last indices
  	// with no previous element
    return findLCIS(m - 1, n - 1, -1, a, b, memo);
}

int main() {

    vector<int> a = { 3, 4, 9, 1 };
    vector<int> b = { 5, 3, 8, 9, 10, 2, 1 };
    cout << LCIS(a, b);
    return 0;
}
Java
// A Java program to find length of the Longest Common
// Increasing Subsequence (LCIS) using memoization

import java.io.*;

class GfG {
       static int findLCIS(int i, int j, int prevIndex, 
                           int[] a, int[] b, int[][][] memo) {
         
        // Base case: If either array is fully traversed
        if (i < 0 || j < 0) 
          return 0;

        // If the result has already been computed, return it
        if (memo[i][j][prevIndex + 1] != -1) 
          return memo[i][j][prevIndex + 1];

        int include = 0;
        int exclude = 0;

        // If the current elements match and
        // satisfy the increasing condition
        if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])) {
         
          // Include the current element
            include = 1 + findLCIS(i - 1, j - 1, i, a, b, memo); 
        }

        // Explore excluding the current element from either array
        exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b, memo),
                           findLCIS(i, j - 1, prevIndex, a, b, memo));

        // Store the result in the memo table and return it
        memo[i][j][prevIndex + 1] = Math.max(include, exclude);
        return memo[i][j][prevIndex + 1];
      }

    // Function to initialize the memo table and start the recursion
     static int LCIS(int[] a, int[] b) {
        int m = a.length;
        int n = b.length;
       
        // Initialize the memoization table with
       // -1 (indicating uncomputed states)
        int[][][] memo = new int[m][n][m + 1];
        for (int[][] table : memo) {
            for (int[] row : table) {
                java.util.Arrays.fill(row, -1);
            }
        }

        // Start recursion from the last indices with no previous element
        return findLCIS(m - 1, n - 1, -1, a, b, memo);
    }
  
    public static void main (String[] args) {
        
        int[] a = {3, 4, 9, 1 };
        int[] b = {5, 3, 8, 9, 10, 2, 1};
        System.out.println(LCIS(a, b));
    }
}
Python
# A Python program to find length of the Longest Common
# Increasing Subsequence (LCIS) using memoization
def findLCIS(i, j, prev_index, a, b, memo):
  
    # Base case: If either array is fully traversed
    if i < 0 or j < 0:
        return 0

    # If the result has already been computed, return it
    if memo[i][j][prev_index + 1] != -1:
        return memo[i][j][prev_index + 1]

    include = 0
    exclude = 0

    # If the current elements match and satisfy the increasing condition
    if a[i] == b[j] and (prev_index == -1 or a[i] < a[prev_index]):
      
         # Include the current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b, memo) 

    # Explore excluding the current element from either array
    exclude = max(findLCIS(i - 1, j, prev_index, a, b, memo),
                  findLCIS(i, j - 1, prev_index, a, b, memo))

    # Store the result in the memo table and return it
    memo[i][j][prev_index + 1] = max(include, exclude)
    return memo[i][j][prev_index + 1]

def LCIS(a, b):
    m = len(a)
    n = len(b)
    
    # Initialize the memoization table with -1
    # (indicating uncomputed states)
    memo = [[[ -1 for _ in range(m + 1)] for _ in range(n)] for _ in range(m)]

    # Start recursion from the last indices with 
    # no previous element
    return findLCIS(m - 1, n - 1, -1, a, b, memo)

a = [3, 4, 9, 1 ]
b = [5, 3, 8, 9, 10, 2, 1]
print(LCIS(a, b))
C#
// A C# program to find length of the Longest Common
// Increasing Subsequence (LCIS) using memoization
using System;

class GfG {
  
    // Recursive function with memoization to find LCIS
    static int FindLCIS(int i, int j, int prevIndex,
                                int[] a, int[] b,
                                int[, , ] memo){
      
        // Base case: If either array is fully traversed
        if (i < 0 || j < 0)
            return 0;

        // If the result has already been computed, return
        // it
        if (memo[i, j, prevIndex + 1] != -1)
            return memo[i, j, prevIndex + 1];

        int include = 0;
        int exclude = 0;

        // If the current elements match and satisfy the
        // increasing condition
        if (a[i] == b[j]
            && (prevIndex == -1
                || a[i] < a[prevIndex])) {
          
          // Include the current element
            include
                = 1
                  + FindLCIS(
                      i - 1, j - 1, i, a, b,
                      memo); 
        }

        // Explore excluding the current element from either
        // array
        exclude = Math.Max(
            FindLCIS(i - 1, j, prevIndex, a, b, memo),
            FindLCIS(i, j - 1, prevIndex, a, b,
                     memo));

        // Store the result in the memo table and return it
        memo[i, j, prevIndex + 1]
            = Math.Max(include, exclude);
        return memo[i, j, prevIndex + 1];
    }

    // Function to initialize the memo table and start the
    // recursion
    static int LCIS(int[] a, int[] b){
        int m = a.Length;
        int n = b.Length;

        // Initialize the memoization table with -1
        // (indicating uncomputed states)
        int[, , ] memo = new int[m, n, m + 1];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < m + 1; k++) {
                    memo[i, j, k] = -1;
                }
            }
        }

        // Start recursion from the last indices with no
        // previous element
        return FindLCIS(m - 1, n - 1, -1, a, b, memo);
    }

    static void Main(string[] args){
        int[] a = {3, 4, 9, 1 };
        int[] b = { 5, 3, 8, 9, 10, 2, 1 };
        Console.WriteLine(LCIS(a, b));
    }
}
JavaScript
// A Javascript program to find length of the Longest Common
// Increasing Subsequence (LCIS) using memoization
function findLCIS(i, j, prevIndex, a, b, memo) {

    // Base case: If either array is fully traversed
    if (i < 0 || j < 0)
        return 0;

    // If the result has already been computed, return it
    if (memo[i][j][prevIndex + 1] !== -1)
        return memo[i][j][prevIndex + 1];

    let include = 0;
    let exclude = 0;

    // If the current elements match and satisfy the
    // increasing condition
    if (a[i] === b[j]
        && (prevIndex === -1
            || a[i] < a[prevIndex])) {
            
            // Include the current element
        include = 1
                  + findLCIS(
                      i - 1, j - 1, i, a, b,
                      memo); 
    }

    // Explore excluding the current element from either
    // array
    exclude = Math.max(
        findLCIS(i - 1, j, prevIndex, a, b, memo),
        findLCIS(i, j - 1, prevIndex, a, b, memo));

    // Store the result in the memo table and return it
    memo[i][j][prevIndex + 1] = Math.max(include, exclude);
    return memo[i][j][prevIndex + 1];
}

function LCIS(arr1, arr2) {
    const m = a.length;
    const n = b.length;
    
    // Initialize the memoization table with -1 (indicating
    // uncomputed states)
    const memo = Array.from(
        {length : m},
        () => Array.from({length : n},
                         () => Array(m + 1).fill(-1)));

    // Start recursion from the last indices with no
    // previous element
    return findLCIS(m - 1, n - 1, -1, a, b, memo);
}

const a = [ 3, 4, 9, 1 ];
const b = [ 5, 3, 8, 9, 10, 2, 1];
console.log(LCIS(a, b));

Output
2

Using Bottom-Up DP (Tabulation) - O(m*n) Time and O(n) Space

The idea is to iterate of every index j of b[] for every index i in a[]. We use a linear array dp of length n intialized with zero to keep track of the LCIS ending on jth index of b[]. We also use a variable currentLength to store the length of the LCIS for the current element of a[]. This variable helps to keep track of the LCIS ending at the previous index of a[] but not including the current element in a[].

  • If a[i] is equal to b[j], then found a potential element of the LCIS that ends at b[j]. At this point, we can update dp[j] to be the maximum of its current value and currentLength + 1. This is because currentLength keeps track of the longest LCIS that ends at a previous index in a[].
  • If a[i] > b[j], it means that b[j] can be part of an increasing subsequence that ends with a[i]. Hence, we need to update the currentLength to be the maximum value between currentLength and dp[j]. This ensures that currentLength holds the length of the longest subsequence ending at any previous element b[k] (where k < j).

After iterating through all elements of a[] and b[], the value of dp[] will hold the lengths of LCIS ending at each index of b[]. The maximum value in the dp[] array will be the length of the Longest Common Increasing Subsequence.

C++
// C++ Program to find length of the Longest Common
// Increasing Subsequence (LCIS) using tabulation
#include <bits/stdc++.h>
using namespace std;

int LCIS(vector<int> &a, vector<int> &b) {
    int m = a.size();
    int n = b.size();

    // Initialize a DP array to store lengths of LCIS 
  	// ending at each index of b
    vector<int> dp(n, 0);

    // Iterate through each element in a
    for (int i = 0; i < m; i++) {
      
        // Start from the end of b to avoid overwriting
      	// dp[j] during iteration
        int currentLength = 0;

        // Iterate through each element in b to compare with a[i]
        for (int j = 0; j < n; j++) {

            // If a[i] == b[j], we may have found a 
          	// new LCIS ending at j in b
            if (a[i] == b[j]) {
                dp[j] = max(dp[j], currentLength + 1);
            }

            // If a[i] > b[j], it means b[j] could 
          	// be part of an increasing subsequence
            else if (a[i] > b[j]) {

                // Update currentLength with the
              	// longest LCIS ending at b[j]
                currentLength = max(currentLength, dp[j]);
            }
        }
    }

    // The maximum value in dp[] is the length of 
  	// the longest common increasing subsequence
    return *max_element(dp.begin(), dp.end());
}

int main() {
    vector<int> a = {3, 4, 9, 1 };
    vector<int> b = {5, 3, 8, 9, 10, 2, 1};
    cout << LCIS(a, b);
    return 0;
}
Java
// Java Program to find length of the Longest Common
// Increasing Subsequence (LCIS) using tabulation
import java.util.*;

class GfG {
    
     static int LCIS(int[] a, int[] b) {
        int m = a.length;
        int n = b.length;

        // Initialize a linear DP array to store
        // lengths of LCIS ending at each index of arr2
        int[] dp = new int[n];

        // Iterate through each element in arr1
        for (int i = 0; i < m; i++) {

            // Start from the end of arr2 to avoid
            // overwriting dp[j] during iteration
            int currentLength = 0;

            // Iterate through each element in arr2
            // to compare with arr1[i]
            for (int j = 0; j < n; j++) {

                // If arr1[i] == arr2[j], we may have found 
                // a new LCIS ending at j in arr2
                if (a[i] == b[j]) {
                    dp[j] = Math.max(dp[j], currentLength + 1);
                }

                // If arr1[i] > arr2[j], it means arr2[j] could 
                // be part of an increasing subsequence
                else if (a[i] > b[j]) {

                    // Update currentLength with the longest
                    // LCIS ending at arr2[j]
                    currentLength = Math.max(currentLength, dp[j]);
                }
            }
        }

        // The maximum value in dp[] is the length of the
        // longest common increasing subsequence
        int result = 0;
        for (int i = 0; i < n; i++) {
            result = Math.max(result, dp[i]);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] a = {3, 4, 9, 1 };
        int[] b = {5, 3, 8, 9, 10, 2, 1};
        System.out.println(LCIS(a, b));
    }
}
Python
# Java Program to find length of the Longest Common
# Increasing Subsequence (LCIS) using tabulation
def LCIS(a, b):
    m = len(a)
    n = len(b)

    # Initialize a DP array to store lengths 
    # of LCIS ending at each index of b
    dp = [0] * n

    # Iterate through each element in a
    for i in range(m):
        currentLength = 0

        # Iterate through each element in b
        for j in range(n):
          
            # If a[i] == b[j], we may have found a
            # new LCIS ending at j in b
            if a[i] == b[j]:
                dp[j] = max(dp[j], currentLength + 1)
                
            # If a[i] > b[j], it means b[j] could be
            # part of an increasing subsequence
            elif a[i] > b[j]:
                currentLength = max(currentLength, dp[j])

    # The maximum value in dp[] is the length of the
    # longest common increasing subsequence
    return max(dp)


a = [3, 4, 9, 1 ]
b = [5, 3, 8, 9, 10, 2, 1]
print(LCIS(a, b)) 
C#
// C# Program to find length of the Longest Common
// Increasing Subsequence (LCIS) using tabulation
using System;

class GfG {
    static int LCIS(int[] a, int[] b) {
        int m = a.Length;
        int n = b.Length;

        // Initialize a DP array to store lengths
      	// of LCIS ending at each index of b
        int[] dp = new int[n];

        // Iterate through each element in a
        for (int i = 0; i < m; i++) {
            int currentLength = 0;

            // Iterate through each element in b
            for (int j = 0; j < n; j++) {
              
                // If a[i] == b[j], we may have found
              	// a new LCIS ending at j in b
                if (a[i] == b[j]) {
                    dp[j] = Math.Max(dp[j], currentLength + 1);
                }
              
                // If a[i] > b[j], it means b[j] could be
              	// part of an increasing subsequence
                else if (a[i] > b[j]) {
                    currentLength = Math.Max(currentLength, dp[j]);
                }
            }
        }

        // The maximum value in dp[] is the length of the
      	// longest common increasing subsequence
        int result = 0;
        foreach (int value in dp) {
            result = Math.Max(result, value);
        }

        return result;
    }

    static void Main() {
        int[] a = { 3, 4, 9, 1 };
        int[] b = {5, 3, 8, 9, 10, 2, 1 };
        Console.WriteLine(LCIS(a, b));
    }
}
JavaScript
// Javascript Program to find length of the Longest
// Common Increasing Subsequence (LCIS) using tabulation
function LCIS(a, b) {
    const m = a.length;
    const n = b.length;

    // Initialize a DP array to store lengths of LCIS ending
    // at each index of b
    let dp = new Array(n).fill(0);

    // Iterate through each element in a
    for (let i = 0; i < m; i++) {
        let currentLength = 0;

        // Iterate through each element in b
        for (let j = 0; j < n; j++) {
        
            // If a[i] == b[j], we may have found a new LCIS
            // ending at j in b
            if (a[i] === b[j]) {
                dp[j] = Math.max(dp[j], currentLength + 1);
            }
            
            // If a[i] > b[j], it means b[j] could be part
            // of an increasing subsequence
            else if (a[i] > b[j]) {
                currentLength
                    = Math.max(currentLength, dp[j]);
            }
        }
    }

    // The maximum value in dp[] is the length of the
    // longest common increasing subsequence
    return Math.max(...dp);
}

const a = [ 3, 4, 9, 1  ];
const b = [ 5, 3, 8, 9, 10, 2, 1 ];
console.log(LCIS(a, b));

Output
2

Next Article

Similar Reads