Minimize insertions and deletions in given array A[] to make it identical to array B[]
Given two arrays A[] and B[] of length N and M respectively, the task is to find the minimum number of insertions and deletions on the array A[], required to make both the arrays identical.
Note: Array B[] is sorted and all its elements are distinct, operations can be performed at any index not necessarily at the end.
Example:
Input: A[] = {1, 2, 5, 3, 1}, B[] = {1, 3, 5}
Output: 4
Explanation: In 1st operation, delete A[1] from array A[] and in 2nd operation, insert 3 at that position. In 3rd and 4th operation, delete A[3] and A[4]. Hence, A[] = {1, 3, 5} = B[] in 4 operations which is the minimum possible.
Input: A[] = {1, 4}, B[] = {1, 4}
Output: 0
Approach: The given problem can be solved by observing the fact that the most optimal choice of elements that must not be deleted from the array A[] are the elements of the Longest Increasing Subsequence among the common elements in A[] and B[]. Therefore, the above problem can be solved by storing the common elements of the array A[] and B[] in a vector and finding the LIS using this algorithm. Thereafter, all the elements other than that of LIS can be deleted from A[], and the remaining elements that are in B[] but not in A[] can be inserted.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minInsAndDel( int A[], int B[], int n, int m)
{
vector< int > common;
unordered_set< int > s;
for ( int i = 0; i < m; i++) {
s.insert(B[i]);
}
for ( int i = 0; i < n; i++) {
if (s.find(A[i]) != s.end()) {
common.push_back(A[i]);
}
}
vector< int > lis;
for ( auto e : common) {
auto it = lower_bound(
lis.begin(), lis.end(), e);
if (it != lis.end())
*it = e;
else
lis.push_back(e);
}
int ans;
ans = m - lis.size();
ans += n - lis.size();
return ans;
}
int main()
{
int N = 5, M = 3;
int A[] = { 1, 2, 5, 3, 1 };
int B[] = { 1, 3, 5 };
cout << minInsAndDel(A, B, N, M) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int lower_bound( int arr[], int X)
{
int mid;
int N = arr.length;
int low = 0 ;
int high = N;
while (low < high) {
mid = low + (high - low) / 2 ;
if (X <= arr[mid]) {
high = mid;
}
else {
low = mid + 1 ;
}
}
if (low < N && arr[low] < X) {
low++;
}
return low;
}
static int minInsAndDel( int A[], int B[], int n, int m)
{
int [] common = new int [n];
int k = 0 ;
HashSet<Integer> s= new HashSet<Integer>();
for ( int i = 0 ; i < m; i++) {
s.add(B[i]);
}
for ( int i = 0 ; i < n; i++) {
if (s.contains(A[i]) == false ) {
common[k++] = A[i];
}
}
int [] lis = new int [n];
k = 0 ;
ArrayList<Integer> LIS = new ArrayList<Integer>();
for ( int e : common) {
int it = lower_bound(lis, e);
if (it <lis.length)
it = e;
else {
lis[k++] = e;
LIS.add(e);
}
}
int ans;
ans = m - LIS.size()- 1 ;
ans = ans+ n - LIS.size()- 1 ;
return ans;
}
public static void main(String[] args)
{
int N = 5 , M = 3 ;
int A[] = { 1 , 2 , 5 , 3 , 1 };
int B[] = { 1 , 3 , 5 };
System.out.println(minInsAndDel(A, B, N, M));
}
}
|
Python3
from bisect import bisect_left
def minInsAndDel(A, B, n, m):
common = []
s = set ()
for i in range ( 0 , m):
s.add(B[i])
for i in range ( 0 , n):
if (A[i] in s):
common.append(A[i])
lis = []
for e in common:
it = bisect_left(lis, e, 0 , len (lis))
if (it ! = len (lis)):
lis[it] = e
else :
lis.append(e)
ans = 0
ans = m - len (lis)
ans + = n - len (lis)
return ans
if __name__ = = "__main__" :
N = 5
M = 3
A = [ 1 , 2 , 5 , 3 , 1 ]
B = [ 1 , 3 , 5 ]
print (minInsAndDel(A, B, N, M))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int lower_bound( int [] arr, int X)
{
int mid;
int N = arr.Length;
int low = 0;
int high = N;
while (low < high) {
mid = low + (high - low) / 2;
if (X <= arr[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
if (low < N && arr[low] < X) {
low++;
}
return low;
}
static int minInsAndDel( int [] A, int [] B, int n, int m)
{
int [] common = new int [n];
int k = 0;
HashSet< int > s = new HashSet< int >();
for ( int i = 0; i < m; i++) {
s.Add(B[i]);
}
for ( int i = 0; i < n; i++) {
if (s.Contains(A[i]) == false ) {
common[k++] = A[i];
}
}
int [] lis = new int [n];
k = 0;
List< int > LIS = new List< int >();
foreach ( int e in common)
{
int it = lower_bound(lis, e);
if (it < lis.Length)
it = e;
else {
lis[k++] = e;
LIS.Add(e);
}
}
int ans;
ans = m - LIS.Count - 1;
ans = ans + n - LIS.Count - 1;
return ans;
}
public static void Main( string [] args)
{
int N = 5, M = 3;
int [] A = { 1, 2, 5, 3, 1 };
int [] B = { 1, 3, 5 };
Console.WriteLine(minInsAndDel(A, B, N, M));
}
}
|
Javascript
<script>
function minInsAndDel(A, B, n, m) {
let common = [];
let s = new Set();
for (let i = 0; i < m; i++) {
s.add(B[i]);
}
for (let i = 0; i < n; i++) {
if (s.has(A[i])) {
common.push(A[i]);
}
}
let lis = [];
for (e of common) {
let it = lower_bound(lis, lis.length, e);
if (lis.includes(it))
it = e;
else
lis.push(e);
}
let ans;
ans = m - lis.length;
ans += n - lis.length;
return ans;
}
function lower_bound(arr, N, X)
{
let mid;
let low = 0;
let high = N;
while (low < high) {
mid = Math.floor(low + (high - low) / 2);
if (X <= arr[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
if (low < N && arr[low] < X) {
low++;
}
return low;
}
let N = 5, M = 3;
let A = [1, 2, 5, 3, 1];
let B = [1, 3, 5];
document.write(minInsAndDel(A, B, N, M));
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Another Approach:
- Find the common elements in arrays A and B:
Traverse through arrays A and B, and for each element of A that is present in B, add it to a vector or list of common elements.
- Find the Longest Increasing Subsequence (LIS) among the common elements:
Find the LIS of the common elements using any standard LIS algorithm, such as dynamic programming, binary search, or segment trees. The length of the LIS will give the number of elements in A that need to be retained to make it identical to B.
- Calculate the minimum number of insertions and deletions required:
The minimum number of insertions and deletions required can be calculated as follows: Number of deletions = length of A – length of LIS
Number of insertions = length of B – length of LIS
Total number of operations = Number of deletions + Number of insertions
- Return the answer:
Return the total number of operations as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minInsAndDel( int A[], int B[], int n, int m)
{
vector< int > common;
for ( int i = 0; i < m; i++) {
if (binary_search(A, A + n, B[i])) {
common.push_back(B[i]);
}
}
vector< int > lis;
for ( auto e : common) {
auto it = lower_bound(
lis.begin(), lis.end(), e);
if (it != lis.end())
*it = e;
else
lis.push_back(e);
}
int ans;
int total = n + m;
int lis_length = lis.size();
ans = total - 2 * lis_length;
return ans;
}
int main()
{
int N = 5, M = 3;
int A[] = { 1, 2, 5, 3, 1 };
int B[] = { 1, 3, 5 };
cout << minInsAndDel(A, B, N, M) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int minInsAndDel( int A[], int B[], int n, int m) {
ArrayList<Integer> common = new ArrayList<Integer>();
for ( int i = 0 ; i < m; i++) {
if (Arrays.binarySearch(A, B[i]) >= 0 ) {
common.add(B[i]);
}
}
ArrayList<Integer> lis = new ArrayList<Integer>();
for ( int e : common) {
int idx = Collections.binarySearch(lis, e);
if (idx >= 0 )
lis.set(idx, e);
else
lis.add(-(idx + 1 ), e);
}
int ans;
int total = n + m;
int lis_length = lis.size();
ans = total - 2 * lis_length;
return ans;
}
public static void main(String[] args) {
int N = 5 , M = 3 ;
int A[] = { 1 , 2 , 5 , 3 , 1 };
int B[] = { 1 , 3 , 5 };
System.out.println(minInsAndDel(A, B, N, M));
}
}
|
Python3
from typing import List
import bisect
def minInsAndDel(A: List [ int ], B: List [ int ], n: int , m: int ) - > int :
common = []
for i in range (m):
if B[i] in A:
common.append(B[i])
lis = []
for e in common:
idx = bisect.bisect_right(lis, e)
if idx < len (lis):
lis[idx] = e
else :
lis.append(e)
ans = 0
total = n + m
lis_length = len (lis)
ans = total - 2 * lis_length
return ans
N, M = 5 , 3
A = [ 1 , 2 , 5 , 3 , 1 ]
B = [ 1 , 3 , 5 ]
print (minInsAndDel(A, B, N, M))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static int MinInsAndDel( int [] A, int [] B, int n, int m)
{
List< int > common = new List< int >();
for ( int i = 0; i < m; i++)
{
if (Array.BinarySearch(A, B[i]) >= 0)
{
common.Add(B[i]);
}
}
List< int > lis = new List< int >();
foreach ( var e in common)
{
var index = lis.BinarySearch(e);
if (index < 0)
{
lis.Insert(~index, e);
}
}
int ans;
int total = n + m;
int lis_length = lis.Count();
ans = total - 2 * lis_length;
return ans;
}
public static void Main()
{
int N = 5, M = 3;
int [] A = { 1, 2, 5, 3, 1 };
int [] B = { 1, 3, 5 };
Console.WriteLine(MinInsAndDel(A, B, N, M));
}
}
|
Javascript
function minInsAndDel(A, B, n, m) {
let common = [];
for (let i = 0; i < m; i++) {
if (A.includes(B[i])) {
common.push(B[i]);
}
}
let lis = [];
for (let i = 0; i < common.length; i++) {
let e = common[i];
let index = lis.findIndex((x) => x === e);
if (index === -1) {
lis.splice(~index, 0, e);
}
}
let ans;
let total = n + m;
let lis_length = lis.length;
ans = total - 2 * lis_length + Math.abs(n - m);
return ans;
}
let N = 5,
M = 3;
let A = [1, 2, 5, 3, 1];
let B = [1, 3, 5];
console.log(minInsAndDel(A, B, N, M));
|
Time Complexity: O(N*logN)
Auxiliary Space: O(N)
Last Updated :
25 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...