给定两个字符串A和B ,任务是按字典顺序查找字符串B的最小排列,使其包含字符串A中的每个子字符串作为其子字符串。如果不可能有这样的有效安排,则打印“ -1” 。
例子:
Input: A = “aa”, B = “ababab”
Output: aaabbb
Explanation:
All possible substrings of A are (‘a’, ‘a’, ‘aa’)
Rearrange string B to “aaabb”.
Now “aaabb” is the lexicographically the smallest arrangement of B which contains all the substrings of A.
Input: A = “aaa”, B = “ramialsadaka”
Output: aaaaadiklmrs
Explanation:
All possible substrings of A are (‘a’, ‘aa’, ‘aaa’)
Rearrange string B to “aaaaadiklmrs”.
Now “aaaaadiklmrs” is the lexicographically smallest arrangement of B which contains all the substrings of A.
朴素方法:最简单的方法是生成字符串B 的所有可能排列,然后从所有这些排列中,按字典顺序找到包含A 的所有子串的最小排列。
时间复杂度: O(N!)
辅助空间: O(1)
高效方法:为了优化上述方法,主要观察是包含A 的所有子串的最小字符串是字符串A本身。因此,对于要重新排序的字符串B并包含A 的所有子字符串,它必须包含A作为子字符串。仅当字符串B中每个字符的频率大于或等于其在A 中的频率时,重新排序的字符串B 才能包含A作为其子字符串。以下是步骤:
- 计算数组freq[]中字符串B中每个字符的频率,然后从中减去字符串A 中相应字符的频率。
- 为了形成字典序最小的字符串,初始化一个空字符串result ,然后附加所有剩余的字符,这些字符的值小于字符串A的第一个字符。
- 在将等于第一个字符A 的所有字符附加到结果之前,请检查是否有任何字符小于字符串A 中的第一个字符。如果是,则首先将 A 附加到 result ,然后将所有剩余的字符附加到 A 的第一个字符,以使重新排序的字符串字典顺序最小。
- 否则,追加所有剩余的 A[0],然后追加 A。
- 最后,将剩余的字符附加到结果中。
- 完成上述步骤后,打印字符串result 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to reorder the string B
// to contain all the substrings of A
string reorderString(string A, string B)
{
// Find length of strings
int size_a = A.length();
int size_b = B.length();
// Initialize array to count the
// frequencies of the character
int freq[300] = { 0 };
// Counting frequencies of
// character in B
for (int i = 0; i < size_b; i++)
freq[B[i]]++;
// Find remaining character in B
for (int i = 0; i < size_a; i++)
freq[A[i]]--;
for (int j = 'a'; j <= 'z'; j++) {
if (freq[j] < 0)
return "-1";
}
// Declare the reordered string
string answer;
for (int j = 'a'; j < A[0]; j++)
// Loop until freq[j] > 0
while (freq[j] > 0) {
answer.push_back(j);
// Decrement the value
// from freq array
freq[j]--;
}
int first = A[0];
for (int j = 0; j < size_a; j++) {
// Check if A[j] > A[0]
if (A[j] > A[0])
break;
// Check if A[j] < A[0]
if (A[j] < A[0]) {
answer += A;
A.clear();
break;
}
}
// Append the remaining characters
// to the end of the result
while (freq[first] > 0) {
answer.push_back(first);
--freq[first];
}
answer += A;
for (int j = 'a'; j <= 'z'; j++)
// Push all the values from
// frequency array in the answer
while (freq[j]--)
answer.push_back(j);
// Return the answer
return answer;
}
// Driver Code
int main()
{
// Given strings A and B
string A = "aa";
string B = "ababab";
// Function Call
cout << reorderString(A, B);
return 0;
}
Java
// Java program for
// the above approach
class GFG{
// Function to reorder the String B
// to contain all the subStrings of A
static String reorderString(char []A,
char []B)
{
// Find length of Strings
int size_a = A.length;
int size_b = B.length;
// Initialize array to count the
// frequencies of the character
int freq[] = new int[300];
// Counting frequencies of
// character in B
for (int i = 0; i < size_b; i++)
freq[B[i]]++;
// Find remaining character in B
for (int i = 0; i < size_a; i++)
freq[A[i]]--;
for (int j = 'a'; j <= 'z'; j++)
{
if (freq[j] < 0)
return "-1";
}
// Declare the reordered String
String answer = "";
for (int j = 'a'; j < A[0]; j++)
// Loop until freq[j] > 0
while (freq[j] > 0)
{
answer+=j;
// Decrement the value
// from freq array
freq[j]--;
}
int first = A[0];
for (int j = 0; j < size_a; j++)
{
// Check if A[j] > A[0]
if (A[j] > A[0])
break;
// Check if A[j] < A[0]
if (A[j] < A[0])
{
answer += String.valueOf(A);
A = new char[A.length];
break;
}
}
// Append the remaining characters
// to the end of the result
while (freq[first] > 0)
{
answer += String.valueOf((char)first);
--freq[first];
}
answer += String.valueOf(A);
for (int j = 'a'; j <= 'z'; j++)
// Push all the values from
// frequency array in the answer
while (freq[j]-- > 0)
answer += ((char)j);
// Return the answer
return answer;
}
// Driver Code
public static void main(String[] args)
{
// Given Strings A and B
String A = "aa";
String B = "ababab";
// Function Call
System.out.print(reorderString(A.toCharArray(),
B.toCharArray()));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
# Function to reorder the B
# to contain all the substrings of A
def reorderString(A, B):
# Find length of strings
size_a = len(A)
size_b = len(B)
# Initialize array to count the
# frequencies of the character
freq = [0] * 300
# Counting frequencies of
# character in B
for i in range(size_b):
freq[ord(B[i])] += 1
# Find remaining character in B
for i in range(size_a):
freq[ord(A[i])] -= 1
for j in range(ord('a'), ord('z') + 1):
if (freq[j] < 0):
return "-1"
# Declare the reordered string
answer = []
for j in range(ord('a'), ord(A[0])):
# Loop until freq[j] > 0
while (freq[j] > 0):
answer.append(j)
# Decrement the value
# from freq array
freq[j] -= 1
first = A[0]
for j in range(size_a):
# Check if A[j] > A[0]
if (A[j] > A[0]):
break
# Check if A[j] < A[0]
if (A[j] < A[0]):
answer += A
A = ""
break
# Append the remaining characters
# to the end of the result
while (freq[ord(first)] > 0):
answer.append(first)
freq[ord(first)] -= 1
answer += A
for j in range(ord('a'), ord('z') + 1):
# Push all the values from
# frequency array in the answer
while (freq[j]):
answer.append(chr(j))
freq[j] -= 1
# Return the answer
return "".join(answer)
# Driver Code
if __name__ == '__main__':
# Given strings A and B
A = "aa"
B = "ababab"
# Function call
print(reorderString(A, B))
# This code is contributed by mohit kumar 29
C#
// C# program for
// the above approach
using System;
class GFG{
// Function to reorder the String B
// to contain all the subStrings of A
static String reorderString(char []A,
char []B)
{
// Find length of Strings
int size_a = A.Length;
int size_b = B.Length;
// Initialize array to count the
// frequencies of the character
int []freq = new int[300];
// Counting frequencies of
// character in B
for (int i = 0; i < size_b; i++)
freq[B[i]]++;
// Find remaining character in B
for (int i = 0; i < size_a; i++)
freq[A[i]]--;
for (int j = 'a'; j <= 'z'; j++)
{
if (freq[j] < 0)
return "-1";
}
// Declare the reordered String
String answer = "";
for (int j = 'a'; j < A[0]; j++)
// Loop until freq[j] > 0
while (freq[j] > 0)
{
answer+=j;
// Decrement the value
// from freq array
freq[j]--;
}
int first = A[0];
for (int j = 0; j < size_a; j++)
{
// Check if A[j] > A[0]
if (A[j] > A[0])
break;
// Check if A[j] < A[0]
if (A[j] < A[0])
{
answer += String.Join("", A);
A = new char[A.Length];
break;
}
}
// Append the remaining characters
// to the end of the result
while (freq[first] > 0)
{
answer += String.Join("", (char)first);
--freq[first];
}
answer += String.Join("", A);
for (int j = 'a'; j <= 'z'; j++)
// Push all the values from
// frequency array in the answer
while (freq[j]-- > 0)
answer += ((char)j);
// Return the answer
return answer;
}
// Driver Code
public static void Main(String[] args)
{
// Given Strings A and B
String A = "aa";
String B = "ababab";
// Function Call
Console.Write(reorderString(A.ToCharArray(),
B.ToCharArray()));
}
}
// This code is contributed by Rajput-Ji
Javascript
aaabbb
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。