最小化给定数组 A[] 中的插入和删除,使其与数组 B[] 相同
给定两个长度分别为N和M的数组A[]和B[] ,任务是找到数组A[]上插入和删除的最小数量,这需要使两个数组相同。
注意:数组B[]是排序的,它的所有元素都是不同的,可以在任何索引处执行操作,不一定在末尾。
例子:
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
方法:给定的问题可以通过观察以下事实来解决:不能从数组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)