Prerequisites : LCS, LIS
Given two arrays, find length of the longest common increasing subsequence [LCIS] and print one of such sequences (multiple sequences may exist)
Suppose we consider two arrays –
arr1[] = {3, 4, 9, 1} and
arr2[] = {5, 3, 8, 9, 10, 2, 1}
Our answer would be {3, 9} as this is the longest common subsequence which is increasing also.
The idea is to use dynamic programming here as well. We store the longest common increasing sub-sequence ending at each index of arr2[]. We create an auxiliary array table[] such that table[j] stores length of LCIS ending with arr2[j]. At the end, we return maximum value from this table. For filling values in this table, we traverse all elements of arr1[] and for every element arr1[i], we traverse all elements of arr2[]. If we find a match, we update table[j] with length of current LCIS. To maintain current LCIS, we keep checking valid table[j] values.
Below is the program to find length of LCIS.
C++
#include<bits/stdc++.h>
using namespace std;
int LCIS( int arr1[], int n, int arr2[], int m)
{
int table[m];
for ( int j=0; j<m; j++)
table[j] = 0;
for ( int i=0; i<n; i++)
{
int current = 0;
for ( int j=0; j<m; j++)
{
if (arr1[i] == arr2[j])
if (current + 1 > table[j])
table[j] = current + 1;
if (arr1[i] > arr2[j])
if (table[j] > current)
current = table[j];
}
}
int result = 0;
for ( int i=0; i<m; i++)
if (table[i] > result)
result = table[i];
return result;
}
int main()
{
int arr1[] = {3, 4, 9, 1};
int arr2[] = {5, 3, 8, 9, 10, 2, 1};
int n = sizeof (arr1)/ sizeof (arr1[0]);
int m = sizeof (arr2)/ sizeof (arr2[0]);
cout << "Length of LCIS is "
<< LCIS(arr1, n, arr2, m);
return (0);
}
|
Java
import java.io.*;
class GFG {
static int LCIS( int arr1[], int n, int arr2[],
int m)
{
int table[] = new int [m];
for ( int j = 0 ; j < m; j++)
table[j] = 0 ;
for ( int i = 0 ; i < n; i++)
{
int current = 0 ;
for ( int j = 0 ; j < m; j++)
{
if (arr1[i] == arr2[j])
if (current + 1 > table[j])
table[j] = current + 1 ;
if (arr1[i] > arr2[j])
if (table[j] > current)
current = table[j];
}
}
int result = 0 ;
for ( int i= 0 ; i<m; i++)
if (table[i] > result)
result = table[i];
return result;
}
public static void main(String[] args)
{
int arr1[] = { 3 , 4 , 9 , 1 };
int arr2[] = { 5 , 3 , 8 , 9 , 10 , 2 , 1 };
int n = arr1.length;
int m = arr2.length;
System.out.println( "Length of LCIS is " +
LCIS(arr1, n, arr2, m));
}
}
|
Python 3
def LCIS(arr1, n, arr2, m):
table = [ 0 ] * m
for j in range (m):
table[j] = 0
for i in range (n):
current = 0
for j in range (m):
if (arr1[i] = = arr2[j]):
if (current + 1 > table[j]):
table[j] = current + 1
if (arr1[i] > arr2[j]):
if (table[j] > current):
current = table[j]
result = 0
for i in range (m):
if (table[i] > result):
result = table[i]
return result
if __name__ = = "__main__" :
arr1 = [ 3 , 4 , 9 , 1 ]
arr2 = [ 5 , 3 , 8 , 9 , 10 , 2 , 1 ]
n = len (arr1)
m = len (arr2)
print ( "Length of LCIS is" ,
LCIS(arr1, n, arr2, m))
|
C#
using System;
class GFG {
static int LCIS( int []arr1, int n,
int []arr2, int m)
{
int []table = new int [m];
for ( int j = 0; j < m; j++)
table[j] = 0;
for ( int i = 0; i < n; i++)
{
int current = 0;
for ( int j = 0; j < m; j++)
{
if (arr1[i] == arr2[j])
if (current + 1 > table[j])
table[j] = current + 1;
if (arr1[i] > arr2[j])
if (table[j] > current)
current = table[j];
}
}
int result = 0;
for ( int i = 0; i < m; i++)
if (table[i] > result)
result = table[i];
return result;
}
public static void Main()
{
int []arr1 = {3, 4, 9, 1};
int []arr2 = {5, 3, 8, 9, 10, 2, 1};
int n = arr1.Length;
int m = arr2.Length;
Console.Write( "Length of LCIS is " +
LCIS(arr1, n, arr2, m));
}
}
|
PHP
<?php
function LCIS( $arr1 , $n , $arr2 , $m )
{
$table = Array();
for ( $j = 0; $j < $m ; $j ++)
$table [ $j ] = 0;
for ( $i = 0; $i < $n ; $i ++)
{
$current = 0;
for ( $j = 0; $j < $m ; $j ++)
{
if ( $arr1 [ $i ] == $arr2 [ $j ])
if ( $current + 1 > $table [ $j ])
$table [ $j ] = $current + 1;
if ( $arr1 [ $i ] > $arr2 [ $j ])
if ( $table [ $j ] > $current )
$current = $table [ $j ];
}
}
$result = 0;
for ( $i = 0; $i < $m ; $i ++)
if ( $table [ $i ] > $result )
$result = $table [ $i ];
return $result ;
}
$arr1 = array (3, 4, 9, 1);
$arr2 = array (5, 3, 8, 9, 10, 2, 1);
$n = sizeof( $arr1 );
$m = sizeof( $arr2 );
echo "Length of LCIS is " ,
LCIS( $arr1 , $n , $arr2 , $m );
?>
|
Javascript
<script>
function LCIS(arr1, n, arr2, m)
{
let table = [];
for (let j = 0; j < m; j++)
table[j] = 0;
for (let i = 0; i < n; i++)
{
let current = 0;
for (let j = 0; j < m; j++)
{
if (arr1[i] == arr2[j])
if (current + 1 > table[j])
table[j] = current + 1;
if (arr1[i] > arr2[j])
if (table[j] > current)
current = table[j];
}
}
let result = 0;
for (let i=0; i<m; i++)
if (table[i] > result)
result = table[i];
return result;
}
let arr1 = [3, 4, 9, 1];
let arr2 = [5, 3, 8, 9, 10, 2, 1];
let n = arr1.length;
let m = arr2.length;
document.write( "Length of LCIS is " +
LCIS(arr1, n, arr2, m));
</script>
|
OutputLength of LCIS is 2
Time Complexity: O(n*m), where n and m represents the size of the given two arrays.
Auxiliary Space: O(m), where m represents the size of the given second array.
Approach#2: Using brute force
We can find the longest common increasing subsequence (LCIS) of two arrays by using dynamic programming. We will use a matrix dp[][] to store the LCIS of two arrays. The dp[i][j] will represent the length of the LCIS that ends at the i-th index of arr1 and j-th index of arr2. We can compute the dp matrix by iterating through each element of arr1 and arr2 and updating the matrix based on the following conditions:
If arr1[i] and arr2[j] are equal, then dp[i][j] = 1 + max(dp[k][l]) where 0 ≤ k < i and 0 ≤ l < j.
If arr1[i] and arr2[j] are not equal, then dp[i][j] = max(dp[k][j]) where 0 ≤ k < i.
If arr1[i] and arr2[j] are not equal, then dp[i][j] = max(dp[i][l]) where 0 ≤ l < j.
Once we have computed the dp matrix, we can find the LCIS by backtracking from the maximum value in the matrix and following the same conditions as above.
Algorithm
1. Initialize the dp matrix of size (len(arr1)+1) x (len(arr2)+1) with zeros.
2. Initialize the max_lcis_length to 0.
3. Initialize the max_lcis_index to None.
4. Iterate through each element of arr1 and arr2.
5. If arr1[i] and arr2[j] are equal, then dp[i+1][j+1] = 1 + max(dp[k+1][l+1]) where 0 ≤ k < i and 0 ≤ l < j.
6. If arr1[i] and arr2[j] are not equal, then dp[i+1][j+1] = max(dp[k+1][j+1]) where 0 ≤ k < i.
7. If arr1[i] and arr2[j] are not equal, then dp[i+1][j+1] = max(dp[i+1][l+1]) where 0 ≤ l < j.
8. If dp[i+1][j+1] > max_lcis_length, then set max_lcis_length to dp[i+1][j+1] and max_lcis_index to (i, j).
9. Backtrack from the max_lcis_index to find the LCIS by following the same conditions as above.
10. Return the LCIS and its length.
Python3
import itertools
def lcis(arr1, arr2):
lcis = []
lcis_length = 0
for i in range ( 1 , min ( len (arr1), len (arr2)) + 1 ):
for seq1 in itertools.combinations(arr1, i):
if seq1 ! = tuple ( sorted (seq1)):
continue
for seq2 in itertools.combinations(arr2, i):
if seq2 ! = tuple ( sorted (seq2)):
continue
if set (seq1) = = set (seq2):
lcis_length = i
lcis = seq1
return lcis_length
arr1 = [ 3 , 4 , 9 , 1 ]
arr2 = [ 5 , 3 , 8 , 9 , 10 , 2 , 1 ]
print (lcis(arr1, arr2))
|
Time Complexity: O(n^4) where n is the length of the longer array. This is because we are computing the dp matrix by iterating through each element of arr1 and arr2 and then iterating through all possible pairs of indices (k,l) and (i,j). Backtracking from the max_lcis_index takes O(n) time.
Space Complexity: O(n^2) as we are using a matrix of size (len(arr1)+1) x (len(arr2)+1) to store the LCIS of two arrays.
This article is contributed Rachit Belwariar. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.