703368. Longest Common Increasing Subsequence
Longest Common Increasing Subsequence
Slug: longest-common-increasing-subsequence1437
Difficulty: Medium
Id: 703368
Topic Tags: Arrays, Dynamic Programming, Data Structures, Algorithms
Company Tags: None
Summary
Given two sequences of integers A and B, find the length of the longest common increasing subsequence. A subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements. The problem requires us to identify the longest such subsequence that is also increasing, i.e., each element is greater than its predecessor.
Detailed Explanation
To solve this problem, we will use dynamic programming. We initialize a 2D array dp where dp[i][j] represents the length of the longest common increasing subsequence between the first i elements of A and the first j elements of B. We fill up the dp array by iterating over all possible subsequences of A and B.
Here's a step-by-step breakdown of the solution:
- Initialize
dp[0][0] = 0, as there is no common increasing subsequence between an empty sequence and another. - For each element
ainAand each elementbinB, check ifa <= b. If this condition is met, it means that the current elements of both sequences are in increasing order. In this case, we updatedp[i][j] = dp[i-1][j-1] + 1, as we found a common increasing subsequence. - Move diagonally upwards and leftwards from each cell in
dpto fill up the entire array.
Here's an ASCII art diagram illustrating the dynamic programming approach:
A | 0 | 1 | 2 | ... | n
---+---+---+---+----+---
B | 0 | 1 | 2 | ... | m
Time complexity: O(nm) Space complexity: O(nm)
Optimized Solutions
Java
public int longestCommonIncreasingSubsequence(int[] A, int[] B) {
int[][] dp = new int[A.length+1][B.length+1];
for (int i = 0; i <= A.length; i++) {
for (int j = 0; j <= B.length; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
} else if (A[i-1] <= B[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[A.length][B.length];
}