📌  相关文章
📜  最小化给定数组 A[] 中的插入和删除,使其与数组 B[] 相同

📅  最后修改于: 2022-05-13 01:57:47.536000             🧑  作者: Mango

最小化给定数组 A[] 中的插入和删除,使其与数组 B[] 相同

给定两个长度分别为NM的数组A[]B[] ,任务是找到数组A[]上插入和删除的最小数量,这需要使两个数组相同。
注意:数组B[]是排序的,它的所有元素都是不同的,可以在任何索引处执行操作,不一定在末尾。

例子:

方法:给定的问题可以通过观察以下事实来解决:不能从数组A[]中删除的元素的最优选择是A[]B[]中公共元素中最长递增子序列的元素.因此,可以通过将数组A[]B[]的公共元素存储在一个向量中并使用该算法找到 LIS 来解决上述问题。此后,可以从A[]中删除除 LIS 之外的所有元素,并且可以插入B[]中但不在A[]中的其余元素。

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
// Function to find minimum operations
// to convert array A to B using
// insertions and deletion opertations
int minInsAndDel(int A[], int B[], int n, int m)
{
 
    // Stores the common elements in A and B
    vector common;
    unordered_set s;
 
    // Loop to iterate over B
    for (int i = 0; i < m; i++) {
        s.insert(B[i]);
    }
 
    // Loop to iterate over A
    for (int i = 0; i < n; i++) {
 
        // If current element is also present
        // in array B
        if (s.find(A[i]) != s.end()) {
            common.push_back(A[i]);
        }
    }
 
    // Stores the Longest Increasing Subsequence
    // among the common elements in A and B
    vector lis;
 
    // Loop to find the LIS among the common
    // elements in A and B
    for (auto e : common) {
        auto it = lower_bound(
            lis.begin(), lis.end(), e);
 
        if (it != lis.end())
            *it = e;
        else
            lis.push_back(e);
    }
 
    // Stores the final answer
    int ans;
 
    // Count of elements to be inserted in A[]
    ans = m - lis.size();
 
    // Count of elements to be deleted from A[]
    ans += n - lis.size();
 
    // Return Answer
    return ans;
}
 
// Driver Code
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
/*package whatever //do not write package name here */
import java.util.*;
 
class GFG
{
   
  // Function to implement lower_bound
static int lower_bound(int arr[], int X)
{
    int mid;
    int N = arr.length;
   
    // Initialise starting index and
    // ending index
    int low = 0;
    int high = N;
  
    // Till low is less than high
    while (low < high) {
        mid = low + (high - low) / 2;
  
        // If X is less than or equal
        // to arr[mid], then find in
        // left subarray
        if (X <= arr[mid]) {
            high = mid;
        }
  
        // If X is greater arr[mid]
        // then find in right subarray
        else {
            low = mid + 1;
        }
    }
    
    // if X is greater than arr[n-1]
    if(low < N && arr[low] < X) {
       low++;
    }
        
    // Return the lower_bound index
    return low;
}
  
    // Function to find minimum operations
    // to convert array A to B using
    // insertions and deletion opertations
    static int minInsAndDel(int A[], int B[], int n, int m)
    {
 
        // Stores the common elements in A and B
        int[] common = new int[n];
        int k = 0;
        HashSet s= new HashSet();
 
        // Loop to iterate over B
        for (int i = 0; i < m; i++) {
            s.add(B[i]);
        }
 
        // Loop to iterate over A
        for (int i = 0; i < n; i++) {
 
            // If current element is also present
            // in array B
            if (s.contains(A[i]) == false) {
                common[k++] = A[i];
            }
        }
 
        // Stores the Longest Increasing Subsequence
        // among the common elements in A and B
        int[] lis = new int[n];
        k = 0;
      ArrayList LIS = new ArrayList();
       
        // Loop to find the LIS among the common
        // elements in A and B
        for (int e : common) {
            int it = lower_bound(lis, e);
 
            if (it 


Python3
# python program of the above approach
from bisect import bisect_left
 
# Function to find minimum operations
# to convert array A to B using
# insertions and deletion opertations
def minInsAndDel(A, B, n, m):
 
    # Stores the common elements in A and B
    common = []
    s = set()
 
    # Loop to iterate over B
    for i in range(0, m):
        s.add(B[i])
 
    # Loop to iterate over A
    for i in range(0, n):
 
        # If current element is also present
        # in array B
        if (A[i] in s):
            common.append(A[i])
 
    # Stores the Longest Increasing Subsequence
    # among the common elements in A and B
    lis = []
 
    # Loop to find the LIS among the common
    # elements in A and B
    for e in common:
        it = bisect_left(lis, e, 0, len(lis))
 
        if (it != len(lis)):
            lis[it] = e
        else:
            lis.append(e)
 
    # Stores the final answer
    ans = 0
 
    # Count of elements to be inserted in A[]
    ans = m - len(lis)
 
    # Count of elements to be deleted from A[]
    ans += n - len(lis)
 
    # Return Answer
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    N = 5
    M = 3
    A = [1, 2, 5, 3, 1]
    B = [1, 3, 5]
 
    print(minInsAndDel(A, B, N, M))
 
    # This code is contributed by rakeshsahni


C#
/*package whatever //do not write package name here */
using System;
using System.Collections.Generic;
 
class GFG {
 
    // Function to implement lower_bound
    static int lower_bound(int[] arr, int X)
    {
        int mid;
        int N = arr.Length;
 
        // Initialise starting index and
        // ending index
        int low = 0;
        int high = N;
 
        // Till low is less than high
        while (low < high) {
            mid = low + (high - low) / 2;
 
            // If X is less than or equal
            // to arr[mid], then find in
            // left subarray
            if (X <= arr[mid]) {
                high = mid;
            }
 
            // If X is greater arr[mid]
            // then find in right subarray
            else {
                low = mid + 1;
            }
        }
 
        // if X is greater than arr[n-1]
        if (low < N && arr[low] < X) {
            low++;
        }
 
        // Return the lower_bound index
        return low;
    }
 
    // Function to find minimum operations
    // to convert array A to B using
    // insertions and deletion opertations
    static int minInsAndDel(int[] A, int[] B, int n, int m)
    {
 
        // Stores the common elements in A and B
        int[] common = new int[n];
        int k = 0;
        HashSet s = new HashSet();
 
        // Loop to iterate over B
        for (int i = 0; i < m; i++) {
            s.Add(B[i]);
        }
 
        // Loop to iterate over A
        for (int i = 0; i < n; i++) {
 
            // If current element is also present
            // in array B
            if (s.Contains(A[i]) == false) {
                common[k++] = A[i];
            }
        }
 
        // Stores the Longest Increasing Subsequence
        // among the common elements in A and B
        int[] lis = new int[n];
        k = 0;
        List LIS = new List();
 
        // Loop to find the LIS among the common
        // elements in A and B
        foreach(int e in common)
        {
            int it = lower_bound(lis, e);
 
            if (it < lis.Length)
                it = e;
            else {
                lis[k++] = e;
                LIS.Add(e);
            }
        }
 
        // Stores the final answer
        int ans;
 
        // Count of elements to be inserted in A[]
        ans = m - LIS.Count - 1;
 
        // Count of elements to be deleted from A[]
        ans = ans + n - LIS.Count - 1;
 
        // Return Answer
        return ans;
    }
 
    // Driver Code
    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));
    }
}
 
// This code is contributed by ukasp.


Javascript


输出
4

时间复杂度: O(N*log N)
辅助空间: O(N)