📌  相关文章
📜  最小化要添加到给定数组中的元素,使其包含另一个给定数组作为其子序列|套装2

📅  最后修改于: 2021-05-13 22:20:01             🧑  作者: Mango

给定一个包含N个不同整数的数组A []和另一个包含M个整数的数组B [] ,任务是找到要添加到数组B []的最小元素数,以使数组A []成为数组B []的子序列。

例子:

天真的方法:有关解决问题的最简单方法,请参阅本文的上一篇文章。

时间复杂度: O(N * 2 M )
辅助空间: O(M + N)

动态编程方法:有关基于最长公共子序列的方法,请参阅本文的上一篇文章。

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

高效的方法:这个想法类似于从数组B []中找到最长递增子序列( LIS )。请按照以下步骤解决问题:

  • 考虑数组B的元素[]其存在于所述阵列A [],并且阵列A [的每个元素的索引]存储在地图
  • 然后,使用二进制搜索(由升序组成的索引)找到LIS数组subseq []
  • 最后,要插入到数组B []中的元素的最小数量等于N – len(LIS) ,其中len(LIS)是使用上述步骤中的二进制搜索来计算的。

下面是上述方法的实现:

C++
// C++ program for the
// above approach
#include 
using namespace std;
 
// Function to return minimum
// element to be added in array
// B so that array A become
// subsequence of array B
int minElements(int A[], int B[],
                int N, int M)
{
  // Stores indices of the
  // array elements
  map map;
 
  // Iterate over the array
  for (int i = 0; i < N; i++)
  {
    // Store the indices of
    // the array elements
    map[A[i]] = i;
  }
 
  // Stores the LIS
  vector subseq;
 
  int l = 0, r = -1;
 
  for (int i = 0; i < M; i++)
  {
    // Check if element B[i]
    // is in array A[]
    if (map.find(B[i]) !=
        map.end())
    {
      int e = map[B[i]];
 
      // Perform Binary Search
      while (l <= r)
      {
        // Find the value of
        // mid m
        int m = l + (r - l) / 2;
 
        // Update l and r
        if (subseq[m] < e)
          l = m + 1;
        else
          r = m - 1;
      }
 
      // If found better element
      // 'e' for pos r + 1
      if (r + 1 < subseq.size())
      {
        subseq[r + 1] = e;
      }
 
      // Otherwise, extend the
      // current subsequence
      else
      {
        subseq.push_back(e);
      }
 
      l = 0;
      r = subseq.size() - 1;
    }
  }
 
  // Return the answer
  return N - subseq.size();
}
 
// Driver code
int main()
{
  // Given arrays
  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]);
 
  // Function Call
  cout << minElements(A, B,
                      M, N);
 
  return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java program for the above approach
 
import java.util.*;
import java.lang.*;
 
class GFG {
 
    // Function to return minimum element
    // to be added in array B so that array
    // A become subsequence of array B
    static int minElements(
        int[] A, int[] B, int N, int M)
    {
 
        // Stores indices of the
        // array elements
        Map map
            = new HashMap<>();
 
        // Iterate over the array
        for (int i = 0;
             i < A.length; i++) {
 
            // Store the indices of
            // the array elements
            map.put(A[i], i);
        }
 
        // Stores the LIS
        ArrayList subseq
            = new ArrayList<>();
 
        int l = 0, r = -1;
 
        for (int i = 0; i < M; i++) {
 
            // Check if element B[i]
            // is in array A[]
            if (map.containsKey(B[i])) {
 
                int e = map.get(B[i]);
 
                // Perform Binary Search
                while (l <= r) {
 
                    // Find the value of
                    // mid m
                    int m = l + (r - l) / 2;
 
                    // Update l and r
                    if (subseq.get(m) < e)
                        l = m + 1;
                    else
                        r = m - 1;
                }
 
                // If found better element
                // 'e' for pos r + 1
                if (r + 1 < subseq.size()) {
                    subseq.set(r + 1, e);
                }
 
                // Otherwise, extend the
                // current subsequence
                else {
                    subseq.add(e);
                }
 
                l = 0;
                r = subseq.size() - 1;
            }
        }
 
        // Return the answer
        return N - subseq.size();
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given arrays
        int[] A = { 1, 2, 3, 4, 5 };
        int[] B = { 2, 5, 6, 4, 9, 12 };
 
        int M = A.length;
        int N = B.length;
 
        // Function Call
        System.out.println(
            minElements(A, B, M, N));
    }
}


Python3
# Python3 program for the above approach
 
# Function to return minimum element
# to be added in array B so that array
# A become subsequence of array B
def minElements(A, B, N, M):
     
    # Stores indices of the
    # array elements
    map = {}
 
    # Iterate over the array
    for i in range(len(A)):
 
        # Store the indices of
        # the array elements
        map[A[i]] = i
  
    # Stores the LIS
    subseq = []
 
    l = 0
    r = -1
 
    for i in range(M):
 
        # Check if element B[i]
        # is in array A[]
        if B[i] in map:
            e = map[B[i]]
 
            # Perform Binary Search
            while (l <= r):
 
                # Find the value of
                # mid m
                m = l + (r - l) // 2
 
                # Update l and r
                if (subseq[m] < e):
                    l = m + 1
                else:
                    r = m - 1
 
            # If found better element
            # 'e' for pos r + 1
            if (r + 1 < len(subseq)):
                subseq[r + 1]= e
 
            # Otherwise, extend the
            # current subsequence
            else:
                subseq.append(e)
 
            l = 0
            r = len(subseq) - 1
 
    # Return the answer
    return N - len(subseq)
 
# Driver Code
if __name__ == '__main__':
     
    # Given arrays
    A = [ 1, 2, 3, 4, 5 ]
    B = [ 2, 5, 6, 4, 9, 12 ]
 
    M = len(A)
    N = len(B)
 
    # Function call
    print(minElements(A, B, M, N))
 
# This code is contributed by mohit kumar 29


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to return minimum element
// to be added in array B so that array
// A become subsequence of array B
static int minElements(int[] A, int[] B,
                       int N, int M)
{
  // Stores indices of the
  // array elements
  Dictionary map = new Dictionary();
   
  // Iterate over the array
  for (int i = 0;
           i < A.Length; i++)
  {
    // Store the indices of
    // the array elements
    map.Add(A[i], i);
  }
 
  // Stores the LIS
  List subseq = new List();
 
  int l = 0, r = -1;
 
  for (int i = 0; i < M; i++)
  {
    // Check if element B[i]
    // is in array []A
    if (map.ContainsKey(B[i]))
    {
      int e = map[B[i]];
 
      // Perform Binary Search
      while (l <= r)
      {
        // Find the value of
        // mid m
        int m = l + (r - l) / 2;
 
        // Update l and r
        if (subseq[m] < e)
          l = m + 1;
        else
          r = m - 1;
      }
 
      // If found better element
      // 'e' for pos r + 1
      if (r + 1 < subseq.Count)
      {
        subseq[r + 1] = e;
      }
 
      // Otherwise, extend the
      // current subsequence
      else
      {
        subseq.Add(e);
      }
 
      l = 0;
      r = subseq.Count - 1;
    }
  }
 
  // Return the answer
  return N - subseq.Count;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given arrays
  int[] A = {1, 2, 3, 4, 5};
  int[] B = {2, 5, 6, 4, 9, 12};
 
  int M = A.Length;
  int N = B.Length;
 
  // Function Call
  Console.WriteLine(minElements(A, B,
                                M, N));
}
}
 
// This code is contributed by Princi Singh


输出:
3






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