给定两个字符串A和B由小写字母组成,任务是找到从B形成A所需的最小子序列数。如果无法形成,则打印-1。
例子:
Input: A = “aacbe”, B = “aceab”
Output: 3
Explanation:
The minimum number of subsequences required for creating A from B is “aa”, “cb” and “e”.
Input: A = “geeks”, B = “geekofthemonth”
Output: -1
Explanation:
It is not possible to create A, as the character ‘s’ is missing in B.
对于蛮力方法,请参阅此处
将一个字符串转换为另一个字符串所需的最小子序列数
贪婪的方法:
- 创建一个26 * size_of_string_B的二维数组来存储字符索引的出现,并用“无限”值初始化数组。
- 使用字符串B 中字符的索引维护二维数组
- 如果 2D Array 的任何元素的值是无限的,则使用同一行中的下一个值更新该值。
- 将指针的位置初始化为 0
- 迭代字符串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
Javascript
输出:
3
时间复杂度: O(N),其中 N 是要形成的字符串的长度(这里是 A)
辅助空间复杂度: O(N),其中 N 是要形成的字符串的长度(这里是 A)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。