Open In App

Longest Common Increasing Subsequence (LCS + LIS)

Last Updated : 12 Nov, 2025
Comments
Improve
Suggest changes
49 Likes
Like
Report

Given two arrays, a[] and b[], find the length of the longest common increasing subsequence(LCIS).
A subsequence is a sequence that appears in the same relative order in both arrays, but not necessarily consecutively.

The Longest Common Increasing Subsequence (LCIS) is defined as the longest sequence that appears in both arrays and whose elements are in strictly increasing order.
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.

[Naive Approach] Using Recursion - O(2^(m+n)) Time and O(m+n) Space

We need to find a sequence that is common in both arrays and also increasing. If we look closely, we have to compare both arrays and check for elements that appear in both while maintaining the increasing order.
Now, in such problems, we often have choices when two elements are common, we must decide whether to include that element in our subsequence or skip it. Because we have multiple possibilities and need to find the longest valid sequence, recursion naturally fits well here.

The idea behind the recursive approach is we start traversing from the end of both arrays. At every step, we compare the current elements of both arrays.

  • If a[i] == b[j], then this element can be a part of our LCIS — but only if it is smaller than the next element that we have already included in the subsequence (since we are moving from the end toward the beginning and building the sequence in reverse order).
  • If the element cannot be included, we explore both possibilities: Move one step back in the first array or Move one step back in the second array.
  • We then take the maximum result from both choices to ensure we find the longest possible sequence.

So, the recursive relation will explore all combinations to check which common increasing subsequence is the longest.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// Recursive function to find LCIS length
int findLCIS(int i, int j, int prevIndex,
             vector<int> &a, vector<int> &b) {
  
    // Base case: reached start of any array
    if (i < 0 || j < 0)
        return 0;

    int include = 0, exclude = 0;

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

    // Skip current element in either array
    exclude = max(findLCIS(i - 1, j, prevIndex, a, b),
                  findLCIS(i, j - 1, prevIndex, a, b));

    return max(include, exclude);
}

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


//Driver Code Starts
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;
}

//Driver Code Ends
Java
import java.util.Arrays;

class GFG {

    // Recursive function to find LCIS length
    static int findLCIS(int i, int j, int prevIndex,
                        int[] a, int[] b) {

        // Base case: reached start of any array
        if (i < 0 || j < 0)
            return 0;

        int include = 0, exclude = 0;

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

        // Skip current element in either array
        exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b),
                           findLCIS(i, j - 1, prevIndex, a, b));

        return Math.max(include, exclude);
    }

    static int LCIS(int[] a, int[] b) {
        int m = a.length, n = b.length;
        return findLCIS(m - 1, n - 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
# Recursive function to find LCIS length
def findLCIS(i, j, prevIndex, a, b):
    # Base case: reached start of any array
    if i < 0 or j < 0:
        return 0

    include, exclude = 0, 0

    # If elements match and sequence is increasing
    if a[i] == b[j] and (prevIndex == -1 or a[i] < a[prevIndex]):
        # Include current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b)

    # Skip current element in either array
    exclude = max(findLCIS(i - 1, j, prevIndex, a, b),
                  findLCIS(i, j - 1, prevIndex, a, b))

    return max(include, exclude)


def LCIS(a, b):
    m, n = len(a), len(b)
    return findLCIS(m - 1, n - 1, -1, a, b)



#Driver Code Starts
if __name__ == "__main__":
    a = [3, 4, 9, 1]
    b = [5, 3, 8, 9, 10, 2, 1]
    print(LCIS(a, b))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG {
//Driver Code Ends


    // Recursive function to find LCIS length
    static int findLCIS(int i, int j, int prevIndex,
                        int[] a, int[] b) {

        // Base case: reached start of any array
        if (i < 0 || j < 0)
            return 0;

        int include = 0, exclude = 0;

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

        // Skip current element in either array
        exclude = Math.Max(findLCIS(i - 1, j, prevIndex, a, b),
                           findLCIS(i, j - 1, prevIndex, a, b));

        return Math.Max(include, exclude);
    }

    static int LCIS(int[] a, int[] b) {
        int m = a.Length, n = b.Length;
        return findLCIS(m - 1, n - 1, -1, a, b);
    }


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

        Console.WriteLine(LCIS(a, b));
    }
}

//Driver Code Ends
JavaScript
// Recursive function to find LCIS length
function findLCIS(i, j, prevIndex, a, b) {
  
    // Base case: reached start of any array
    if (i < 0 || j < 0)
        return 0;

    let include = 0, exclude = 0;

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

    // Skip current element in either array
    exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b),
                       findLCIS(i, j - 1, prevIndex, a, b));

    return Math.max(include, exclude);
}

function LCIS(a, b) {
    let m = a.length, n = b.length;
    return findLCIS(m - 1, n - 1, -1, a, b);
}


// Driver code
//Driver Code Starts
let a = [3, 4, 9, 1];
let b = [5, 3, 8, 9, 10, 2, 1];

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

//Driver Code Ends

Output
2

[Better Approach 1] Using Top-Down DP (Memoization) - O(m*n*m) Time and O(m*n*m) Space

If we look carefully at the above recursive approach, we can notice that there are many subproblems that we solve again and again during recursion. For example, while calculating the LCIS for a particular combination of indices (i, j, prevIndex), the same state might get recomputed multiple times when reached through different recursive paths. To overcome this issue, we use Memoization (Top-Down Dynamic Programming).

The main idea is to store the results of already computed subproblems so that whenever we encounter the same state again, we can directly use the stored result instead of recomputing it. In this problem, since our recursive function depends on three changing parameters — i, j, and prevIndex — we will create a 3D DP array to store the results of these states. Before solving any subproblem, we first check in the DP array whether the result for the current combination of (i, j, prevIndex) has already been computed.
If it’s already available, we simply return it. Otherwise, we compute it recursively and store the result in the DP table for future use.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// 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>>> &dp) {

    // Base case: reached start of any array
    if (i < 0 || j < 0)
        return 0;

    // Return stored result if already computed
    if (dp[i][j][prevIndex + 1] != -1)
        return dp[i][j][prevIndex + 1];

    int include = 0, exclude = 0;

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

    // Skip current element in either array
    exclude = max(findLCIS(i - 1, j, prevIndex, a, b, dp),
                  findLCIS(i, j - 1, prevIndex, a, b, dp));

    // Store and return result
    return dp[i][j][prevIndex + 1] = max(include, exclude);
}

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

    vector<vector<vector<int>>> dp(m,
        vector<vector<int>>(n, vector<int>(m + 1, -1)));

    return findLCIS(m - 1, n - 1, -1, a, b, dp);
}


//Driver Code Starts
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;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

//Driver Code Ends

class GFG {

    // Recursive function with memoization to find LCIS
    static int findLCIS(int i, int j, int prevIndex, int[] a, int[] b, int[][][] dp) {

        // Base case: reached start of any array
        if (i < 0 || j < 0)
            return 0;

        // Return stored result if already computed
        if (dp[i][j][prevIndex + 1] != -1)
            return dp[i][j][prevIndex + 1];

        int include = 0, exclude = 0;

        // If elements match and sequence is increasing
        if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])) {

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

        // Skip current element in either array
        exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b, dp),
                           findLCIS(i, j - 1, prevIndex, a, b, dp));

        // Store and return result
        return dp[i][j][prevIndex + 1] = Math.max(include, exclude);
    }

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

        int[][][] dp = new int[m][n][m + 1];
        for (int[][] x : dp)
            for (int[] y : x)
                Arrays.fill(y, -1);

        return findLCIS(m - 1, n - 1, -1, a, b, dp);
    }


//Driver Code Starts
    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));
    }
}

//Driver Code Ends
Python
# Recursive function with memoization to find LCIS
def findLCIS(i, j, prevIndex, a, b, dp):

    # Base case: reached start of any array
    if i < 0 or j < 0:
        return 0

    # Return stored result if already computed
    if dp[i][j][prevIndex + 1] != -1:
        return dp[i][j][prevIndex + 1]

    include, exclude = 0, 0

    # If elements match and sequence is increasing
    if a[i] == b[j] and (prevIndex == -1 or a[i] < a[prevIndex]):
        
        # Include current element
        include = 1 + findLCIS(i - 1, j - 1, i, a, b, dp)

    # Skip current element in either array
    exclude = max(findLCIS(i - 1, j, prevIndex, a, b, dp),
                  findLCIS(i, j - 1, prevIndex, a, b, dp))

    # Store and return result
    dp[i][j][prevIndex + 1] = max(include, exclude)
    return dp[i][j][prevIndex + 1]


def LCIS(a, b):
    m, n = len(a), len(b)
    dp = [[[-1 for _ in range(m + 1)] for _ in range(n)] for _ in range(m)]
    return findLCIS(m - 1, n - 1, -1, a, b, dp)



#Driver Code Starts

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

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG {
//Driver Code Ends


    // Recursive function with memoization to find LCIS
    static int findLCIS(int i, int j, int prevIndex, int[] a, 
                                            int[] b, int[,,] dp) {

        // Base case: reached start of any array
        if (i < 0 || j < 0)
            return 0;

        // Return stored result if already computed
        if (dp[i, j, prevIndex + 1] != -1)
            return dp[i, j, prevIndex + 1];

        int include = 0, exclude = 0;

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

        // Skip current element in either array
        exclude = Math.Max(findLCIS(i - 1, j, prevIndex, a, b, dp),
                           findLCIS(i, j - 1, prevIndex, a, b, dp));

        // Store and return result
        dp[i, j, prevIndex + 1] = Math.Max(include, exclude);
        return dp[i, j, prevIndex + 1];
    }

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

        int[,,] dp = new int[m, n, m + 1];
        for (int x = 0; x < m; x++)
            for (int y = 0; y < n; y++)
                for (int z = 0; z < m + 1; z++)
                    dp[x, y, z] = -1;

        return findLCIS(m - 1, n - 1, -1, a, b, dp);
    }


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

        Console.WriteLine(LCIS(a, b));
    }
}

//Driver Code Ends
JavaScript
// Recursive function with memoization to find LCIS
function findLCIS(i, j, prevIndex, a, b, dp) {

    // Base case: reached start of any array
    if (i < 0 || j < 0) return 0;

    // Return stored result if already computed
    if (dp[i][j][prevIndex + 1] !== -1)
        return dp[i][j][prevIndex + 1];

    let include = 0, exclude = 0;

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

    // Skip current element in either array
    exclude = Math.max(findLCIS(i - 1, j, prevIndex, a, b, dp),
                       findLCIS(i, j - 1, prevIndex, a, b, dp));

    // Store and return result
    dp[i][j][prevIndex + 1] = Math.max(include, exclude);
    return dp[i][j][prevIndex + 1];
}

function LCIS(a, b) {
    const m = a.length, n = b.length;
    const dp = Array.from({ length: m }, () =>
        Array.from({ length: n }, () => Array(m + 1).fill(-1))
    );

    return findLCIS(m - 1, n - 1, -1, a, b, dp);
}


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

//Driver Code Ends

Output
2

[Better Approach 2] Using Bottom-Up DP (Tabulation) - O(m*n*m) Time and O(m*n*m) Space

In the previous memoization approach, we used recursion along with a 3D DP array to store already computed results. Although memoization avoids recomputation, it still involves recursive calls, which introduce function call overhead and consume extra stack space.
To make the solution more efficient, we can convert it into an iterative tabulation approach, where we build the solution from the base cases upward this removes the recursion overhead and gives a clearer flow of computation.

We create a 3D DP table dp[i][j][prevIndex + 1], where each cell represents the length of the LCIS. Just like in memoization, we iterate over all indices i and j of arrays a and b. For every combination of (i, j, prevIndex), we compute two possibilities:

Include the element - if element of a and b same and the increasing condition holds:
dp[i][j][prevIndex + 1] = 1 + dp[i-1][j-1][i+1]

Exclude the element - skip one element from either a or b, and take the best of both:
dp[i][j][prevIndex + 1] = max(dp[i-1][j][prevIndex + 1], dp[i][j-1][prevIndex + 1])

We fill this table iteratively starting from smaller indices and gradually building up to larger ones until we reach dp[m-1][n-1][0], which gives the final answer.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


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

    vector<vector<vector<int>>> dp(m, vector<vector<int>>
                                (n, vector<int>(m + 1, 0)));

    // Fill table iteratively
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            for (int prevIndex = -1; prevIndex < m; prevIndex++) {
                int include = 0, exclude = 0;

                // Include current element if it matches
                //and increasing condition holds
                if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])) {
                    if (i > 0 && j > 0)
                        include = 1 + dp[i - 1][j - 1][i + 1]; 
                    else
                        include = 1;
                }

                // Exclude: skip from a or b
                int skipA = (i > 0) ? dp[i - 1][j][prevIndex + 1] : 0;
                int skipB = (j > 0) ? dp[i][j - 1][prevIndex + 1] : 0;
                exclude = max(skipA, skipB);

                dp[i][j][prevIndex + 1] = max(include, exclude);
            }
        }
    }

    return dp[m - 1][n - 1][0]; 
}


//Driver Code Starts
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;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GFG {
//Driver Code Ends


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

        int[][][] dp = new int[m][n][m + 1];

        // Fill table iteratively
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int prevIndex = -1; prevIndex < m; prevIndex++) {
                    int include = 0, exclude = 0;

                    // Include current element if it matches
                    // and increasing condition holds
                    if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex])) {
                        if (i > 0 && j > 0)
                            include = 1 + dp[i - 1][j - 1][i + 1];
                        else
                            include = 1;
                    }

                    // Exclude: skip from a or b
                    int skipA = (i > 0) ? dp[i - 1][j][prevIndex + 1] : 0;
                    int skipB = (j > 0) ? dp[i][j - 1][prevIndex + 1] : 0;
                    exclude = Math.max(skipA, skipB);

                    dp[i][j][prevIndex + 1] = Math.max(include, exclude);
                }
            }
        }

        return dp[m - 1][n - 1][0];
    }


//Driver Code Starts
    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));
    }
}

//Driver Code Ends
Python
def LCIS(a, b):
    m, n = len(a), len(b)

    # 3D DP table
    dp = [[[0] * (m + 1) for _ in range(n)] for _ in range(m)]

    # Fill table iteratively
    for i in range(m):
        for j in range(n):
            for prevIndex in range(-1, m):
                include = 0
                exclude = 0

                # Include current element if it matches
                # and increasing condition holds
                if a[i] == b[j] and (prevIndex == -1 or a[i] < a[prevIndex]):
                    if i > 0 and j > 0:
                        include = 1 + dp[i - 1][j - 1][i + 1]
                    else:
                        include = 1

                # Exclude: skip from a or b
                skipA = dp[i - 1][j][prevIndex + 1] if i > 0 else 0
                skipB = dp[i][j - 1][prevIndex + 1] if j > 0 else 0
                exclude = max(skipA, skipB)

                dp[i][j][prevIndex + 1] = max(include, exclude)

    return dp[m - 1][n - 1][0]
    

    
#Driver Code Starts

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

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG {
//Driver Code Ends

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

        int[,,] dp = new int[m, n, m + 1];

        // Fill table iteratively
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int prevIndex = -1; prevIndex < m; prevIndex++)
                {
                    int include = 0, exclude = 0;

                    // Include current element if it matches
                    // and increasing condition holds
                    if (a[i] == b[j] && (prevIndex == -1 || a[i] < a[prevIndex]))
                    {
                        if (i > 0 && j > 0)
                            include = 1 + dp[i - 1, j - 1, i + 1];
                        else
                            include = 1;
                    }

                    // Exclude: skip from a or b
                    int skipA = (i > 0) ? dp[i - 1, j, prevIndex + 1] : 0;
                    int skipB = (j > 0) ? dp[i, j - 1, prevIndex + 1] : 0;
                    exclude = Math.Max(skipA, skipB);

                    dp[i, j, prevIndex + 1] = Math.Max(include, exclude);
                }
            }
        }

        return dp[m - 1, n - 1, 0];
    }

//Driver Code Starts

    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));
    }
}

//Driver Code Ends
JavaScript
function LCIS(a, b) {
    let m = a.length, n = b.length;

    // 3D DP table
    let dp = Array.from({ length: m }, () => 
             Array.from({ length: n }, () => Array(m + 1).fill(0)));

    // Fill table iteratively
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            for (let prevIndex = -1; prevIndex < m; prevIndex++) {
                let include = 0, exclude = 0;

                // Include current element if it matches
                // and increasing condition holds
                if (a[i] === b[j] && (prevIndex === -1 || a[i] < a[prevIndex])) {
                    if (i > 0 && j > 0)
                        include = 1 + dp[i - 1][j - 1][i + 1];
                    else
                        include = 1;
                }

                // Exclude: skip from a or b
                let skipA = i > 0 ? dp[i - 1][j][prevIndex + 1] : 0;
                let skipB = j > 0 ? dp[i][j - 1][prevIndex + 1] : 0;
                exclude = Math.max(skipA, skipB);

                dp[i][j][prevIndex + 1] = Math.max(include, exclude);
            }
        }
    }

    return dp[m - 1][n - 1][0];
}



//Driver Code Starts
// Example usage
let a = [3, 4, 9, 1];
let b = [5, 3, 8, 9, 10, 2, 1];

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

//Driver Code Ends

Output
2

[Expected Approach] Using 1D Dp - O(m*n) Time and O(n) Space

In the previous 3D DP approach, we observed redundant computations and high memory usage. To optimize both time and space, we can use a 1D DP approach that finds the LCIS efficiently using only linear space.
We iterate through each element of a[], and for every a[i], we compare it with all elements of b[] from left to right. We maintain a variable currentLength that tracks the best LCIS length so far for elements smaller than the current a[i].
While comparing elements, three cases arise:

Case 1: a[i] == b[j]
The current element can be part of an increasing subsequence common to both arrays, so we update:
dp[j] = max(dp[j], currentLength + 1)
This ensures we extend the subsequence correctly when a match is found.

Case 2: a[i] > b[j] Since b[j] is smaller, it can appear before a[i] in an LCIS. So, we update:
currentLength = max(currentLength, dp[j])
This step stores the best subsequence length that can later be extended when a match occurs.

Case 3: a[i] < b[j], b[j] cannot come before a[i] in an increasing subsequence, so we skip it.

After processing all elements, the dp[] array holds the LCIS lengths ending at each index of b[]. The maximum value in dp[] gives the length of the Longest Common Increasing Subsequence.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//Driver Code Ends


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

    // dp[j] stores the length of LCIS ending at b[j]
    vector<int> dp(n, 0);

    // Traverse each element of array a
    for (int i = 0; i < m; i++) {
        int currentLength = 0;

        // Compare current element of a with all elements of b
        for (int j = 0; j < n; j++) {

            //When elements match, extend the LCIS
            if (a[i] == b[j]) {
                dp[j] = max(dp[j], currentLength + 1);
            }

            // If a[i] is greater, update best LCIS so far
            else if (a[i] > b[j]) {
                currentLength = max(currentLength, dp[j]);
            }

        }
    }

    // The maximum value in dp gives final LCIS length
    return *max_element(dp.begin(), dp.end());
}


//Driver Code Starts
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;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GFG {
//Driver Code Ends


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

        // dp[j] stores the length of LCIS ending at b[j]
        int[] dp = new int[n];

        // Traverse each element of array a
        for (int i = 0; i < m; i++) {
            int currentLength = 0;

            // Compare current element of a with all elements of b
            for (int j = 0; j < n; j++) {

                //When elements match, extend the LCIS
                if (a[i] == b[j]) {
                    dp[j] = Math.max(dp[j], currentLength + 1);
                }

                // If a[i] is greater, update best LCIS so far
                else if (a[i] > b[j]) {
                    currentLength = Math.max(currentLength, dp[j]);
                }
            }
        }

        // The maximum value in dp gives final LCIS length
        int ans = 0;
        for (int val : dp)
            ans = Math.max(ans, val);
        return ans;
    }


//Driver Code Starts

    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));
    }
}

//Driver Code Ends
Python
def LCIS(a, b):
    m = len(a)
    n = len(b)

    # dp[j] stores the length of LCIS ending at b[j]
    dp = [0] * n

    # Traverse each element of array a
    for i in range(m):
        currentLength = 0

        # Compare current element of a with all elements of b
        for j in range(n):

            #When elements match, extend the LCIS
            if a[i] == b[j]:
                dp[j] = max(dp[j], currentLength + 1)

            # If a[i] is greater, update best LCIS so far
            elif a[i] > b[j]:
                currentLength = max(currentLength, dp[j])

    # The maximum value in dp gives final LCIS length
    return max(dp)



#Driver Code Starts

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

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
using System.Linq;

class GFG
{
//Driver Code Ends

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

        // dp[j] stores the length of LCIS ending at b[j]
        int[] dp = new int[n];

        // Traverse each element of array a
        for (int i = 0; i < m; i++)
        {
            int currentLength = 0;

            // Compare current element of a with all elements of b
            for (int j = 0; j < n; j++)
            {
                //When elements match, extend the LCIS
                if (a[i] == b[j])
                {
                    dp[j] = Math.Max(dp[j], currentLength + 1);
                }

                // If a[i] is greater, update best LCIS so far
                else if (a[i] > b[j])
                {
                    currentLength = Math.Max(currentLength, dp[j]);
                }
            }
        }

        // The maximum value in dp gives final LCIS length
        return dp.Max();
    }


//Driver Code Starts
    static void Main()
    {
        int[] a = { 3, 4, 9, 1 };
        int[] b = { 5, 3, 8, 9, 10, 2, 1 };
        Console.WriteLine(LCIS(a, b));
    }
}

//Driver Code Ends
JavaScript
function LCIS(a, b) {
    let m = a.length;
    let n = b.length;

    // dp[j] stores the length of LCIS ending at b[j]
    let dp = new Array(n).fill(0);

    // Traverse each element of array a
    for (let i = 0; i < m; i++) {
        let currentLength = 0;

        // Compare current element of a with all elements of b
        for (let j = 0; j < n; j++) {

            //When elements match, extend the LCIS
            if (a[i] === b[j]) {
                dp[j] = Math.max(dp[j], currentLength + 1);
            }

            // If a[i] is greater, update best LCIS so far
            else if (a[i] > b[j]) {
                currentLength = Math.max(currentLength, dp[j]);
            }
        }
    }

    // The maximum value in dp gives final LCIS length
    return Math.max(...dp);
}



//Driver Code Starts
// Driver Code
let a = [3, 4, 9, 1];
let b = [5, 3, 8, 9, 10, 2, 1];
console.log(LCIS(a, b));

//Driver Code Ends

Output
2

Article Tags :

Explore