Minimize Insertions and Deletions to Make Two Arrays Identical

Last Updated : 28 May, 2026

Given two arrays a[] and b[], 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.

Examples:

Input: a[] = [1, 2, 5, 3, 1], b[] = [1, 3, 5]
Output: 4
Explanation:
Delete 2 from a: a[] = [1, 5, 3, 1]
Insert 3 after 1: a[] = [1, 3, 5, 3, 1]
Delete the last two elements: a[] = [1, 3, 5]
Total operations = 1 + 1 + 2 = 4.

Input: a[] = [1, 4], b[] = [1, 4]
Output: 0
Explanation:

Try It Yourself
redirect icon

[Naive Approach] Using Longest Common Subsequence (LCS) DP - O(n * m) Time O(n * m) Space

The idea is to find the Longest Common Subsequence (LCS) between a[] and b[]. The elements that are not part of the LCS are either deleted from a[] or inserted into a[] to make both arrays identical.

C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// Function to find minimum insertions
// and deletions required
int minInsAndDel(vector<int> &a, vector<int> &b)
{
    int n = a.size();
    int m = b.size();

    // dp[i][j] stores length of LCS
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));

    // Build LCS table
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {

            // If elements are equal
            if (a[i - 1] == b[j - 1])
            {
                dp[i][j] = 1 + dp[i - 1][j - 1];
            }

            // Otherwise take maximum
            else
            {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    // Length of LCS
    int lcs = dp[n][m];

    // Store final answer
    return (n - lcs) + (m - lcs);
}

// Driver Code
int main()
{
    vector<int> a = {1, 2, 5, 3, 1};
    vector<int> b = {1, 3, 5};

    cout << minInsAndDel(a, b);

    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function to find minimum insertions
// and deletions required
int minInsAndDel(int *a, int *b, int n, int m)
{
    // dp[i][j] stores length of LCS
    int **dp = (int **)malloc((n + 1) * sizeof(int*));
    for(int i = 0; i <= n; i++)
        dp[i] = (int *)malloc((m + 1) * sizeof(int));

    // Build LCS table
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            // If elements are equal
            if (a[i - 1] == b[j - 1])
            {
                dp[i][j] = 1 + dp[i - 1][j - 1];
            }
            // Otherwise take maximum
            else
            {
                dp[i][j] = (dp[i - 1][j] > dp[i][j - 1])? dp[i - 1][j] : dp[i][j - 1];
            }
        }
    }

    // Length of LCS
    int lcs = dp[n][m];

    // Store final answer
    int ans = (n - lcs) + (m - lcs);

    // Free allocated memory
    for(int i = 0; i <= n; i++)
        free(dp[i]);
    free(dp);

    return ans;
}

// Driver Code
int main()
{
    int a[] = {1, 2, 5, 3, 1};
    int b[] = {1, 3, 5};
    int n = sizeof(a) / sizeof(a[0]);
    int m = sizeof(b) / sizeof(b[0]);

    printf("%d", minInsAndDel(a, b, n, m));

    return 0;
}
Java
import java.util.Arrays;

// Function to find minimum insertions
// and deletions required
public class GfG {
    public static int minInsAndDel(int[] a, int[] b) {
        int n = a.length;
        int m = b.length;

        // dp[i][j] stores length of LCS
        int[][] dp = new int[n + 1][m + 1];

        // Build LCS table
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {

                // If elements are equal
                if (a[i - 1] == b[j - 1]) {
                    dp[i][j] = 1 + dp[i - 1][j - 1];
                }
                // Otherwise take maximum
                else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        // Length of LCS
        int lcs = dp[n][m];

        // Store final answer
        int ans = (n - lcs) + (m - lcs);

        return ans;
    }

    // Driver Code
    public static void main(String[] args) {
        int[] a = {1, 2, 5, 3, 1};
        int[] b = {1, 3, 5};

        System.out.println(minInsAndDel(a, b));
    }
}
Python
def minInsAndDel(a, b):
    n = len(a)
    m = len(b)

    # dp[i][j] stores length of LCS
    dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]

    # Build LCS table
    for i in range(1, n + 1):
        for j in range(1, m + 1):

            # If elements are equal
            if a[i - 1] == b[j - 1]:
                dp[i][j] = 1 + dp[i - 1][j - 1]
            # Otherwise take maximum
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

    # Length of LCS
    lcs = dp[n][m]

    # Store final answer
    ans = (n - lcs) + (m - lcs)

    return ans

# Driver Code
if __name__ == "__main__":
    a = [1, 2, 5, 3, 1]
    b = [1, 3, 5]

    print(minInsAndDel(a, b))
C#
using System;

public class GfG
{
    public static int MinInsAndDel(int[] a, int[] b)
    {
        int n = a.Length;
        int m = b.Length;

        // dp[i][j] stores length of LCS
        int[,] dp = new int[n + 1, m + 1];

        // Build LCS table
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                // If elements are equal
                if (a[i - 1] == b[j - 1])
                {
                    dp[i, j] = 1 + dp[i - 1, j - 1];
                }
                // Otherwise take maximum
                else
                {
                    dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
                }
            }
        }

        // Length of LCS
        int lcs = dp[n, m];

        // Store final answer
        int ans = (n - lcs) + (m - lcs);

        return ans;
    }

    public static void Main()
    {
        int[] a = { 1, 2, 5, 3, 1 };
        int[] b = { 1, 3, 5 };

        Console.WriteLine(MinInsAndDel(a, b));
    }
}
JavaScript
function minInsAndDel(a, b) {
    let n = a.length;
    let m = b.length;

    // dp[i][j] stores length of LCS
    let dp = Array.from(Array(n + 1), () => Array(m + 1).fill(0));

    // Build LCS table
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= m; j++) {

            // If elements are equal
            if (a[i - 1] === b[j - 1]) {
                dp[i][j] = 1 + dp[i - 1][j - 1];
            }
            // Otherwise take maximum
            else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    // Length of LCS
    let lcs = dp[n][m];

    // Store final answer
    let ans = (n - lcs) + (m - lcs);

    return ans;
}

// Driver Code
let a = [1, 2, 5, 3, 1];
let b = [1, 3, 5];

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

Output
4

Time Complexity: O(n * m)
Auxiliary Space: O(n * m)

[Expected Approach] Using Longest Increasing Subsequence (LIS) - O(n log n) Time O(n) Space

The idea is to map each element of a[] to its position in b[] (if it exists) and then find the Longest Increasing Subsequence (LIS) of this mapped sequence. Since b[] is sorted and contains distinct elements, the LIS represents the maximum number of elements already in the correct order, while the remaining elements are handled through insertions and deletions.

C++
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

// Function to find minimum insertions
// and deletions required
int minInsAndDel(vector<int> &a, vector<int> &b)
{
    int n = a.size();
    int m = b.size();

    // Store index of elements in b
    unordered_map<int, int> mp;

    for (int i = 0; i < m; i++)
    {
        mp[b[i]] = i;
    }

    // Store mapped indices
    vector<int> v;

    // Traverse array a
    for (int x : a)
    {

        // If element is present in b
        if (mp.count(x))
        {
            v.push_back(mp[x]);
        }
    }

    // Stores LIS
    vector<int> lis;

    // Find LIS of mapped indices
    for (int x : v)
    {

        // Find position using lower_bound
        auto it = lower_bound(lis.begin(), lis.end(), x);

        // Insert element
        if (it == lis.end())
        {
            lis.push_back(x);
        }

        // Replace element
        else
        {
            *it = x;
        }
    }

    // Length of LCS
    int len = lis.size();

    // Store final answer
    int res = (n - len) + (m - len);

    return res;
}

// Driver Code
int main()
{
    vector<int> a = {1, 2, 5, 3, 1};
    vector<int> b = {1, 3, 5};

    cout << minInsAndDel(a, b);

    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function to find minimum insertions
// and deletions required
int minInsAndDel(int *a, int *b, int n, int m)
{
    int i;

    // Store index of elements in b
    int *mp = (int *)malloc(100000 * sizeof(int));

    for (i = 0; i < 100000; i++)
    {
        mp[i] = -1;
    }

    for (i = 0; i < m; i++)
    {
        mp[b[i]] = i;
    }

    // Store mapped indices
    int *v = (int *)malloc(n * sizeof(int));
    int v_size = 0;

    // Traverse array a
    for (i = 0; i < n; i++)
    {

        // If element is present in b
        if (mp[a[i]] != -1)
        {
            v[v_size++] = mp[a[i]];
        }
    }

    // Stores LIS
    int *lis = (int *)malloc(v_size * sizeof(int));
    int lis_len = 0;

    // Find LIS of mapped indices
    for (i = 0; i < v_size; i++)
    {
        int x = v[i];

        int left = 0;
        int right = lis_len;

        while (left < right)
        {
            int mid = left + (right - left) / 2;

            if (lis[mid] < x)
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }

        // Insert element
        if (left == lis_len)
        {
            lis[lis_len++] = x;
        }

        // Replace element
        else
        {
            lis[left] = x;
        }
    }

    // Length of LCS
    int len = lis_len;

    // Store final answer
    int ans = (n - len) + (m - len);

    free(mp);
    free(v);
    free(lis);

    return ans;
}

// Driver Code
int main()
{
    int a[] = {1, 2, 5, 3, 1};
    int b[] = {1, 3, 5};

    int n = sizeof(a) / sizeof(a[0]);
    int m = sizeof(b) / sizeof(b[0]);

    printf("%d", minInsAndDel(a, b, n, m));

    return 0;
}
Java
import java.util.*;

// Function to find minimum insertions
// and deletions required
public class GfG {
    public static int minInsAndDel(int[] a, int[] b) {
        int n = a.length;
        int m = b.length;

        // Store index of elements in b
        HashMap<Integer, Integer> mp = new HashMap<>();

        for (int i = 0; i < m; i++) {
            mp.put(b[i], i);
        }

        // Store mapped indices
        ArrayList<Integer> v = new ArrayList<>();

        // Traverse array a
        for (int x : a) {
            // If element is present in b
            if (mp.containsKey(x)) {
                v.add(mp.get(x));
            }
        }

        // Stores LIS
        ArrayList<Integer> lis = new ArrayList<>();

        // Find LIS of mapped indices
        for (int x : v) {
            // Find position using lower_bound
            int index = Collections.binarySearch(lis, x);
            if (index < 0) {
                index = - (index + 1);
            }

            // Insert element
            if (index == lis.size()) {
                lis.add(x);
            }
            // Replace element
            else {
                lis.set(index, x);
            }
        }

        // Length of LCS
        int len = lis.size();

        // Store final answer
        int ans = (n - len) + (m - len);

        return ans;
    }

    // Driver Code
    public static void main(String[] args) {
        int[] a = {1, 2, 5, 3, 1};
        int[] b = {1, 3, 5};

        System.out.println(minInsAndDel(a, b));
    }
}
Python
from bisect import bisect_left

# Function to find minimum insertions
# and deletions required
def minInsAndDel(a, b):
    n = len(a)
    m = len(b)

    # Store index of elements in b
    mp = {value: index for index, value in enumerate(b)}

    # Store mapped indices
    v = [mp[x] for x in a if x in mp]

    # Stores LIS
    lis = []

    # Find LIS of mapped indices
    for x in v:
        # Find position using lower_bound
        it = bisect_left(lis, x)

        # Insert element
        if it == len(lis):
            lis.append(x)
        # Replace element
        else:
            lis[it] = x

    # Length of LCS
    len_lis = len(lis)

    # Store final answer
    ans = (n - len_lis) + (m - len_lis)

    return ans

# Driver Code
if __name__ == "__main__":
    a = [1, 2, 5, 3, 1]
    b = [1, 3, 5]

    print(minInsAndDel(a, b))
C#
using System;
using System.Collections.Generic;

class GfG
{
    // Function to find minimum insertions
    // and deletions required
    static int minInsAndDel(int[] a, int[] b)
    {
        int n = a.Length;
        int m = b.Length;

        // Store index of elements in b
        Dictionary<int, int> mp = new Dictionary<int, int>();

        for (int i = 0; i < m; i++)
        {
            mp[b[i]] = i;
        }

        // Store mapped indices
        List<int> v = new List<int>();

        // Traverse array a
        foreach (int x in a)
        {
            // If element is present in b
            if (mp.ContainsKey(x))
            {
                v.Add(mp[x]);
            }
        }

        // Stores LIS
        List<int> lis = new List<int>();

        // Find LIS of mapped indices
        foreach (int x in v)
        {
            // Find position using BinarySearch
            int idx = lis.BinarySearch(x);
            idx = idx < 0? ~idx : idx;

            // Insert element
            if (idx == lis.Count)
            {
                lis.Add(x);
            }
            // Replace element
            else
            {
                lis[idx] = x;
            }
        }

        // Length of LCS
        int len = lis.Count;

        // Store final answer
        int ans = (n - len) + (m - len);

        return ans;
    }

    // Driver Code
    static void Main(string[] args)
    {
        int[] a = { 1, 2, 5, 3, 1 };
        int[] b = { 1, 3, 5 };

        Console.WriteLine(minInsAndDel(a, b));
    }
}
JavaScript
// Function to find minimum insertions
// and deletions required
function minInsAndDel(a, b) {
    let n = a.length;
    let m = b.length;

    // Store index of elements in b
    let mp = new Map();

    for (let i = 0; i < m; i++) {
        mp.set(b[i], i);
    }

    // Store mapped indices
    let v = [];

    // Traverse array a
    for (let x of a) {
        // If element is present in b
        if (mp.has(x)) {
            v.push(mp.get(x));
        }
    }

    // Stores LIS
    let lis = [];

    // Find LIS of mapped indices
    for (let x of v) {
        // Find position using binary search
        let idx = binarySearch(lis, x);

        // Insert element
        if (idx === lis.length) {
            lis.push(x);
        }
        // Replace element
        else {
            lis[idx] = x;
        }
    }

    // Length of LCS
    let len = lis.length;

    // Store final answer
    let ans = (n - len) + (m - len);

    return ans;
}

// Binary search function to find insertion point
function binarySearch(arr, x) {
    let low = 0;
    let high = arr.length - 1;
    while (low <= high) {
        let mid = Math.floor((low + high) / 2);
        if (arr[mid] === x) {
            return mid;
        } else if (arr[mid] < x) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    return low;
}

// Driver Code
let a = [1, 2, 5, 3, 1];
let b = [1, 3, 5];

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

Output
4

Time Complexity: O(n log n)
Auxiliary Space: O(n)

Comment