Given an array A[] consisting of N distinct integers and another array B[] consisting of M integers, the task is to find the minimum number of elements to be added to the array B[] such that the array A[] becomes the subsequence of the array B[].
Examples:
Input: N = 5, M = 6, A[] = {1, 2, 3, 4, 5}, B[] = {2, 5, 6, 4, 9, 12}
Output: 3
Explanation:
Below are the elements that need to be added:
1) Add 1 before element 2 of B[]
2) Add 3 after element 6 of B[]
3) Add 5 in the last position of B[].
Therefore, the resulting array B[] is {1, 2, 5, 6, 3, 4, 9, 12, 5}.
Hence, A[] is the subsequence of B[] after adding 3 elements.
Input: N = 5, M = 5, A[] = {3, 4, 5, 2, 7}, B[] = {3, 4, 7, 9, 2}
Output: 2
Explanation:
Below are the elements that need to be added:
1) Add 5 after element 4.
2) Add 2 after element 5.
Therefore, the resulting array B[] is {3, 4, 5, 2, 7, 9, 2}.
Hence, 2 elements are required to be added.
Naive Approach: Refer to the previous post of this article for the simplest approach to solve the problem.
Time Complexity: O(N * 2M)
Auxiliary Space: O(M + N)
Dynamic Programming Approach: Refer to the previous post of this article for the Longest Common Subsequence based approach.
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)
Efficient Approach: The idea is similar to finding the Longest Increasing Subsequence(LIS) from the array B[]. Follow the steps below to solve the problem:
- Consider elements of array B[] which are present in the array A[], and store the indices of each element of the array A[] in a Map
- Then, find the LIS array subseq[] using Binary Search which consists of the indices in increasing order.
- Finally, the minimum number of elements to be inserted into array B[] is equal to N – len(LIS), where len(LIS) is calculated using Binary Search in the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minElements( int A[], int B[],
int N, int M)
{
map< int , int > map;
for ( int i = 0; i < N; i++)
{
map[A[i]] = i;
}
vector< int > subseq;
int l = 0, r = -1;
for ( int i = 0; i < M; i++)
{
if (map.find(B[i]) !=
map.end())
{
int e = map[B[i]];
while (l <= r)
{
int m = l + (r - l) / 2;
if (subseq[m] < e)
l = m + 1;
else
r = m - 1;
}
if (r + 1 < subseq.size())
{
subseq[r + 1] = e;
}
else
{
subseq.push_back(e);
}
l = 0;
r = subseq.size() - 1;
}
}
return N - subseq.size();
}
int main()
{
int A[] = {1, 2, 3, 4, 5};
int B[] = {2, 5, 6, 4, 9, 12};
int M = sizeof (A) /
sizeof (A[0]);
int N = sizeof (B) /
sizeof (B[0]);
cout << minElements(A, B,
M, N);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG {
static int minElements(
int [] A, int [] B, int N, int M)
{
Map<Integer, Integer> map
= new HashMap<>();
for ( int i = 0 ;
i < A.length; i++) {
map.put(A[i], i);
}
ArrayList<Integer> subseq
= new ArrayList<>();
int l = 0 , r = - 1 ;
for ( int i = 0 ; i < M; i++) {
if (map.containsKey(B[i])) {
int e = map.get(B[i]);
while (l <= r) {
int m = l + (r - l) / 2 ;
if (subseq.get(m) < e)
l = m + 1 ;
else
r = m - 1 ;
}
if (r + 1 < subseq.size()) {
subseq.set(r + 1 , e);
}
else {
subseq.add(e);
}
l = 0 ;
r = subseq.size() - 1 ;
}
}
return N - subseq.size();
}
public static void main(String[] args)
{
int [] A = { 1 , 2 , 3 , 4 , 5 };
int [] B = { 2 , 5 , 6 , 4 , 9 , 12 };
int M = A.length;
int N = B.length;
System.out.println(
minElements(A, B, M, N));
}
}
|
Python3
def minElements(A, B, N, M):
map = {}
for i in range ( len (A)):
map [A[i]] = i
subseq = []
l = 0
r = - 1
for i in range (M):
if B[i] in map :
e = map [B[i]]
while (l < = r):
m = l + (r - l) / / 2
if (subseq[m] < e):
l = m + 1
else :
r = m - 1
if (r + 1 < len (subseq)):
subseq[r + 1 ] = e
else :
subseq.append(e)
l = 0
r = len (subseq) - 1
return N - len (subseq)
if __name__ = = '__main__' :
A = [ 1 , 2 , 3 , 4 , 5 ]
B = [ 2 , 5 , 6 , 4 , 9 , 12 ]
M = len (A)
N = len (B)
print (minElements(A, B, M, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int minElements( int [] A, int [] B,
int N, int M)
{
Dictionary< int ,
int > map = new Dictionary< int ,
int >();
for ( int i = 0;
i < A.Length; i++)
{
map.Add(A[i], i);
}
List< int > subseq = new List< int >();
int l = 0, r = -1;
for ( int i = 0; i < M; i++)
{
if (map.ContainsKey(B[i]))
{
int e = map[B[i]];
while (l <= r)
{
int m = l + (r - l) / 2;
if (subseq[m] < e)
l = m + 1;
else
r = m - 1;
}
if (r + 1 < subseq.Count)
{
subseq[r + 1] = e;
}
else
{
subseq.Add(e);
}
l = 0;
r = subseq.Count - 1;
}
}
return N - subseq.Count;
}
public static void Main(String[] args)
{
int [] A = {1, 2, 3, 4, 5};
int [] B = {2, 5, 6, 4, 9, 12};
int M = A.Length;
int N = B.Length;
Console.WriteLine(minElements(A, B,
M, N));
}
}
|
Javascript
<script>
function minElements(A, B, N, M)
{
var map = new Map();
for ( var i = 0; i < N; i++)
{
map.set(A[i], i);
}
var subseq = [];
var l = 0, r = -1;
for ( var i = 0; i < M; i++)
{
if (map.has(B[i]))
{
var e = map.get(B[i]);
while (l <= r)
{
var m = l + parseInt((r - l) / 2);
if (subseq[m] < e)
l = m + 1;
else
r = m - 1;
}
if (r + 1 < subseq.length)
{
subseq[r + 1] = e;
}
else
{
subseq.push(e);
}
l = 0;
r = subseq.length - 1;
}
}
return N - subseq.length;
}
var A = [1, 2, 3, 4, 5];
var B = [2, 5, 6, 4, 9, 12];
var M = A.length;
var N = B.length;
document.write( minElements(A, B,
M, N));
</script>
|
Time Complexity: O(N logN)
Auxiliary Space: O(N)