📌  相关文章
📜  使用贪婪算法将一个字符串转换为另一个字符串所需的最小子序列数

📅  最后修改于: 2021-09-06 05:37:12             🧑  作者: Mango

给定两个字符串AB由小写字母组成,任务是找到从B形成A所需的最小子序列数。如果无法形成,则打印-1。

例子:

对于蛮力方法,请参阅此处
将一个字符串转换为另一个字符串所需的最小子序列数

贪婪的方法:

  1. 创建一个26 * size_of_string_B的二维数组来存储字符索引的出现,并用“无限”值初始化数组。
  2. 使用字符串B 中字符的索引维护二维数组
  3. 如果 2D Array 的任何元素的值是无限的,则使用同一行中的下一个值更新该值。
  4. 将指针的位置初始化为 0
  5. 迭代字符串A和每个字符-
    • 如果指针的位置为 0 并且该位置在 2D 数组中是无限的,则该字符不存在于字符串B 中
    • 如果二维数组中的值不等于无穷大,则使用二维数组中存在的指针所在位置的值更新该位置的值,因为在子序列中无法考虑它之前的字符。

下面是上述方法的实现。

C++
// C++ implementation for minimum
// number of subsequences required
// to convert one string to another
  
#include 
using namespace std;
  
// Function to find the minimum number
// of subsequences required to convert
// one string to another
// S2 == A and S1 == B
int findMinimumSubsequences(string A,
                            string B){
      
    // At least 1 subsequence is required
    // Even in best case, when A is same as B
    int numberOfSubsequences = 1; 
      
    // size of B
    int sizeOfB = B.size();
      
    // size of A
    int sizeOfA = A.size();
    int inf = 1000000;
  
    // Create an 2D array next[][] 
    // of size 26 * sizeOfB to store 
    // the next occurrence of a character
    // ('a' to 'z') as an index [0, sizeOfA - 1]
    int next[26][sizeOfB];
  
    // Array Initialization with infinite
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < sizeOfB; j++) {
            next[i][j] = inf;
        }
    }
  
    // Loop to Store the values of index
    for (int i = 0; i < sizeOfB; i++) {
        next[B[i] - 'a'][i] = i;
    }
      
    // If the value of next[i][j]
    // is infinite then update it with 
    // next[i][j + 1]
    for (int i = 0; i < 26; i++) {
        for (int j = sizeOfB - 2; j >= 0; j--) {
            if (next[i][j] == inf) {
                next[i][j] = next[i][j + 1];
            }
        }
    }
  
    // Greedy algorithm to obtain the maximum
    // possible subsequence of B to cover the
    // remaining string of A using next subsequence
    int pos = 0;
    int i = 0;
      
    // Loop to iterate over the string A
    while (i < sizeOfA) {
          
        // Condition to check if the character is 
        // not present in the string B
        if (pos == 0 &&
           next[A[i] - 'a'][pos] == inf) {
            numberOfSubsequences = -1;
            break;
        }
          
        // Condition to check if there 
        // is an element in B matching with 
        // character A[i] on or next to B[pos]
        // given by next[A[i] - 'a'][pos]
        else if (pos < sizeOfB &&
                  next[A[i] - 'a'][pos] < inf) {
            int nextIndex = next[A[i] - 'a'][pos] + 1;
            pos = nextIndex;
            i++;
        }
          
        // Condition to check if reached at the end
        // of B or no such element exists on
        // or next to A[pos], thus increment number
        // by one and reinitialise pos to zero
        else {
            numberOfSubsequences++;
            pos = 0;
        }
    }
    return numberOfSubsequences;
}
  
// Driver Code
int main()
{
    string A = "aacbe"; 
    string B = "aceab";
   
cout << findMinimumSubsequences(A, B);
  
    return 0;
}


Java
// Java implementation for minimum
// number of subsequences required
// to convert one String to another
class GFG
{
  
// Function to find the minimum number
// of subsequences required to connvert
// one String to another
// S2 == A and S1 == B
static int findMinimumSubsequences(String A,
                            String B)
{
      
    // At least 1 subsequence is required
    // Even in best case, when A is same as B
    int numberOfSubsequences = 1; 
      
    // size of B
    int sizeOfB = B.length();
      
    // size of A
    int sizeOfA = A.length();
    int inf = 1000000;
  
    // Create an 2D array next[][] 
    // of size 26 * sizeOfB to store 
    // the next occurrence of a character
    // ('a' to 'z') as an index [0, sizeOfA - 1]
    int [][]next = new int[26][sizeOfB];
  
    // Array Initialization with infinite
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < sizeOfB; j++) {
            next[i][j] = inf;
        }
    }
  
    // Loop to Store the values of index
    for (int i = 0; i < sizeOfB; i++) {
        next[B.charAt(i) - 'a'][i] = i;
    }
      
    // If the value of next[i][j]
    // is infinite then update it with 
    // next[i][j + 1]
    for (int i = 0; i < 26; i++) {
        for (int j = sizeOfB - 2; j >= 0; j--) {
            if (next[i][j] == inf) {
                next[i][j] = next[i][j + 1];
            }
        }
    }
  
    // Greedy algorithm to obtain the maximum
    // possible subsequence of B to cover the
    // remaining String of A using next subsequence
    int pos = 0;
    int i = 0;
      
    // Loop to iterate over the String A
    while (i < sizeOfA) {
          
        // Condition to check if the character is 
        // not present in the String B
        if (pos == 0 &&
        next[A.charAt(i)- 'a'][pos] == inf) {
            numberOfSubsequences = -1;
            break;
        }
          
        // Condition to check if there 
        // is an element in B matching with 
        // character A[i] on or next to B[pos]
        // given by next[A[i] - 'a'][pos]
        else if (pos < sizeOfB &&
                next[A.charAt(i) - 'a'][pos] < inf) {
            int nextIndex = next[A.charAt(i) - 'a'][pos] + 1;
            pos = nextIndex;
            i++;
        }
          
        // Condition to check if reached at the end
        // of B or no such element exists on
        // or next to A[pos], thus increment number
        // by one and reinitialise pos to zero
        else {
            numberOfSubsequences++;
            pos = 0;
        }
    }
    return numberOfSubsequences;
}
  
// Driver Code
public static void main(String[] args)
{
    String A = "aacbe"; 
    String B = "aceab";
  
    System.out.print(findMinimumSubsequences(A, B));
}
}
  
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation for minimum
# number of subsequences required
# to convert one to another
  
# Function to find the minimum number
# of subsequences required to convert
# one to another
# S2 == A and S1 == B
def findMinimumSubsequences(A, B):
  
    # At least 1 subsequence is required
    # Even in best case, when A is same as B
    numberOfSubsequences = 1
  
    # size of B
    sizeOfB = len(B)
  
    # size of A
    sizeOfA = len(A)
    inf = 1000000
  
    # Create an 2D array next[][]
    # of size 26 * sizeOfB to store
    # the next occurrence of a character
    # ('a' to 'z') as an index [0, sizeOfA - 1]
    next = [[ inf for i in range(sizeOfB)] for i in range(26)]
  
    # Loop to Store the values of index
    for i in range(sizeOfB):
        next[ord(B[i]) - ord('a')][i] = i
  
    # If the value of next[i][j]
    # is infinite then update it with
    # next[i][j + 1]
    for i in range(26):
        for j in range(sizeOfB-2, -1, -1):
            if (next[i][j] == inf):
                next[i][j] = next[i][j + 1]
  
    # Greedy algorithm to obtain the maximum
    # possible subsequence of B to cover the
    # remaining of A using next subsequence
    pos = 0
    i = 0
  
    # Loop to iterate over the A
    while (i < sizeOfA):
  
        # Condition to check if the character is
        # not present in the B
        if (pos == 0 and
        next[ord(A[i]) - ord('a')][pos] == inf):
            numberOfSubsequences = -1
            break
  
        # Condition to check if there
        # is an element in B matching with
        # character A[i] on or next to B[pos]
        # given by next[A[i] - 'a'][pos]
        elif (pos < sizeOfB and
                next[ord(A[i]) - ord('a')][pos] < inf) :
            nextIndex = next[ord(A[i]) - ord('a')][pos] + 1
            pos = nextIndex
            i += 1
  
        # Condition to check if reached at the end
        # of B or no such element exists on
        # or next to A[pos], thus increment number
        # by one and reinitialise pos to zero
        else :
            numberOfSubsequences += 1
            pos = 0
  
    return numberOfSubsequences
  
# Driver Code
if __name__ == '__main__':
    A = "aacbe"
    B = "aceab"
    print(findMinimumSubsequences(A, B))
      
# This code is contributed by mohit kumar 29


C#
// C# implementation for minimum
// number of subsequences required
// to convert one String to another
using System;
  
class GFG
{
  
// Function to find the minimum number
// of subsequences required to convert
// one String to another
// S2 == A and S1 == B
static int findMinimumSubsequences(String A,
                                   String B)
{
      
    // At least 1 subsequence is required
    // Even in best case, when A is same as B
    int numberOfSubsequences = 1; 
      
    // size of B
    int sizeOfB = B.Length;
      
    // size of A
    int sizeOfA = A.Length;
    int inf = 1000000;
  
    // Create an 2D array next[,] 
    // of size 26 * sizeOfB to store 
    // the next occurrence of a character
    // ('a' to 'z') as an index [0, sizeOfA - 1]
    int [,]next = new int[26,sizeOfB];
  
    // Array Initialization with infinite
    for (int i = 0; i < 26; i++)
    {
        for (int j = 0; j < sizeOfB; j++) 
        {
            next[i, j] = inf;
        }
    }
  
    // Loop to Store the values of index
    for (int i = 0; i < sizeOfB; i++)
    {
        next[B[i] - 'a', i] = i;
    }
      
    // If the value of next[i,j]
    // is infinite then update it with 
    // next[i,j + 1]
    for (int i = 0; i < 26; i++) 
    {
        for (int j = sizeOfB - 2; j >= 0; j--)
        {
            if (next[i, j] == inf) 
            {
                next[i, j] = next[i, j + 1];
            }
        }
    }
  
    // Greedy algorithm to obtain the maximum
    // possible subsequence of B to cover the
    // remaining String of A using next subsequence
    int pos = 0;
    int I = 0;
      
    // Loop to iterate over the String A
    while (I < sizeOfA) 
    {
          
        // Condition to check if the character is 
        // not present in the String B
        if (pos == 0 &&
            next[A[I]- 'a', pos] == inf) 
        {
            numberOfSubsequences = -1;
            break;
        }
          
        // Condition to check if there 
        // is an element in B matching with 
        // character A[i] on or next to B[pos]
        // given by next[A[i] - 'a',pos]
        else if (pos < sizeOfB &&
                next[A[I] - 'a',pos] < inf)
        {
            int nextIndex = next[A[I] - 'a',pos] + 1;
            pos = nextIndex;
            I++;
        }
          
        // Condition to check if reached at the end
        // of B or no such element exists on
        // or next to A[pos], thus increment number
        // by one and reinitialise pos to zero
        else
        {
            numberOfSubsequences++;
            pos = 0;
        }
    }
    return numberOfSubsequences;
}
  
// Driver Code
public static void Main(String[] args)
{
    String A = "aacbe"; 
    String B = "aceab";
  
    Console.Write(findMinimumSubsequences(A, B));
}
}
  
// This code is contributed by 29AjayKumar


输出:
3

时间复杂度: O(N),其中 N 是要形成的字符串的长度(这里是 A)
辅助空间复杂度: O(N),其中 N 是要形成的字符串的长度(这里是 A)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live