给定两个长度相等的字符串S1和S2 ,任务是确定 S2 是否是 S1 的加扰形式。
炒字符串:
给定字符串str ,我们可以通过将其递归地划分为两个非空子字符串来将其表示为二叉树。
注意:加扰字符串与字谜不同
下面是 str = “coder” 的一种可能表示:
coder
/ \
co der
/ \ / \
c o d er
/ \
e r
为了打乱字符串,我们可以选择任何非叶节点并交换它的两个子节点。
假设,我们选择节点“co”并交换它的两个孩子,它产生一个加扰的字符串“ocder”。
ocder
/ \
oc der
/ \ / \
o c d er
/ \
e r
因此,“ocder”是“编码器”的炒字符串。
类似地,如果我们继续交换节点“der”和“er”的子节点,它会产生一个加扰的字符串“ocred” 。
ocred
/ \
oc red
/ \ / \
o c re d
/ \
r e
因此,“光学字符识别”是“编码器”的炒字符串。
例子:
Input: S1=”coder”, S2=”ocder”
Output: Yes
Explanation:
“ocder” is a scrambled form of “coder”
Input: S1=”abcde”, S2=”caebd”
Output: No
Explanation:
“caebd” is not a scrambled form of “abcde”
方法
为了解决这个问题,我们采用了分而治之的方法。
给定两个长度相等的字符串(比如 n+1),S1[0…n] 和 S2[0…n]。如果 S2 是 S1 的加扰形式,则必须存在一个索引 i,使得至少满足以下条件之一:
- S2[0…i] 是 S1[0…i] 的加扰字符串,S2[i+1…n] 是 S1[i+1…n] 的加扰字符串。
- S2[0…i] 是 S1[ni…n] 的加扰字符串,S2[i+1…n] 是 S1[0…ni-1] 的加扰字符串。
注意:此处要考虑的优化步骤是事先检查两个字符串是否互为变位词。如果不是,则表明字符串包含不同的字符,不能是彼此的加扰形式。
下面是上述方法的实现:
C++
// C++ Program to check if a
// given string is a scrambled
// form of another string
#include
using namespace std;
bool isScramble(string S1, string S2)
{
// Strings of non-equal length
// cant' be scramble strings
if (S1.length() != S2.length()) {
return false;
}
int n = S1.length();
// Empty strings are scramble strings
if (n == 0) {
return true;
}
// Equal strings are scramble strings
if (S1 == S2) {
return true;
}
// Check for the condition of anagram
string copy_S1 = S1, copy_S2 = S2;
sort(copy_S1.begin(), copy_S1.end());
sort(copy_S2.begin(), copy_S2.end());
if (copy_S1 != copy_S2) {
return false;
}
for (int i = 1; i < n; i++) {
// Check if S2[0...i] is a scrambled
// string of S1[0...i] and if S2[i+1...n]
// is a scrambled string of S1[i+1...n]
if (isScramble(S1.substr(0, i), S2.substr(0, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(i, n - i))) {
return true;
}
// Check if S2[0...i] is a scrambled
// string of S1[n-i...n] and S2[i+1...n]
// is a scramble string of S1[0...n-i-1]
if (isScramble(S1.substr(0, i),
S2.substr(n - i, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(0, n - i))) {
return true;
}
}
// If none of the above
// conditions are satisfied
return false;
}
// Driver Code
int main()
{
string S1 = "coder";
string S2 = "ocred";
if (isScramble(S1, S2)) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}
Java
// Java program to check if a
// given string is a scrambled
// form of another string
import java.util.*;
class GFG{
static boolean isScramble(String S1,
String S2)
{
// Strings of non-equal length
// cant' be scramble strings
if (S1.length() != S2.length())
{
return false;
}
int n = S1.length();
// Empty strings are scramble strings
if (n == 0)
{
return true;
}
// Equal strings are scramble strings
if (S1.equals(S2))
{
return true;
}
// Converting string to
// character array
char[] tempArray1 = S1.toCharArray();
char[] tempArray2 = S2.toCharArray();
// Checking condition for Anagram
Arrays.sort(tempArray1);
Arrays.sort(tempArray2);
String copy_S1 = new String(tempArray1);
String copy_S2 = new String(tempArray2);
if (!copy_S1.equals(copy_S2))
{
return false;
}
for(int i = 1; i < n; i++)
{
// Check if S2[0...i] is a scrambled
// string of S1[0...i] and if S2[i+1...n]
// is a scrambled string of S1[i+1...n]
if (isScramble(S1.substring(0, i),
S2.substring(0, i)) &&
isScramble(S1.substring(i, n),
S2.substring(i, n)))
{
return true;
}
// Check if S2[0...i] is a scrambled
// string of S1[n-i...n] and S2[i+1...n]
// is a scramble string of S1[0...n-i-1]
if (isScramble(S1.substring(n - i, n),
S2.substring(0, i)) &&
isScramble(S1.substring(0, n - i),
S2.substring(i, n)))
{
return true;
}
}
// If none of the above
// conditions are satisfied
return false;
}
// Driver Code
public static void main(String[] args)
{
String S1 = "coder";
String S2 = "ocred";
if (isScramble(S1, S2))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
}
}
// This code is contributed by dadi madhav
Python3
# Python3 program to check if a
# given string is a scrambled
# form of another string
def isScramble(S1: str, S2: str):
# Strings of non-equal length
# cant' be scramble strings
if len(S1) != len(S2):
return False
n = len(S1)
# Empty strings are scramble strings
if not n:
return True
# Equal strings are scramble strings
if S1 == S2:
return True
# Check for the condition of anagram
if sorted(S1) != sorted(S2):
return False
for i in range(1, n):
# Check if S2[0...i] is a scrambled
# string of S1[0...i] and if S2[i+1...n]
# is a scrambled string of S1[i+1...n]
if (isScramble(S1[:i], S2[:i]) and
isScramble(S1[i:], S2[i:])):
return True
# Check if S2[0...i] is a scrambled
# string of S1[n-i...n] and S2[i+1...n]
# is a scramble string of S1[0...n-i-1]
if (isScramble(S1[-i:], S2[:i]) and
isScramble(S1[:-i], S2[i:])):
return True
# If none of the above
# conditions are satisfied
return False
# Driver Code
if __name__ == "__main__":
S1 = "coder"
S2 = "ocred"
if (isScramble(S1, S2)):
print("Yes")
else:
print("No")
# This code is contributed by sgshah2
C#
// C# program to check if a
// given string is a scrambled
// form of another string
using System;
using System.Collections.Generic;
class GFG {
static bool isScramble(string S1, string S2)
{
// Strings of non-equal length
// cant' be scramble strings
if (S1.Length != S2.Length)
{
return false;
}
int n = S1.Length;
// Empty strings are scramble strings
if (n == 0)
{
return true;
}
// Equal strings are scramble strings
if (S1.Equals(S2))
{
return true;
}
// Converting string to
// character array
char[] tempArray1 = S1.ToCharArray();
char[] tempArray2 = S2.ToCharArray();
// Checking condition for Anagram
Array.Sort(tempArray1);
Array.Sort(tempArray2);
string copy_S1 = new string(tempArray1);
string copy_S2 = new string(tempArray2);
if (!copy_S1.Equals(copy_S2))
{
return false;
}
for(int i = 1; i < n; i++)
{
// Check if S2[0...i] is a scrambled
// string of S1[0...i] and if S2[i+1...n]
// is a scrambled string of S1[i+1...n]
if (isScramble(S1.Substring(0, i),
S2.Substring(0, i)) &&
isScramble(S1.Substring(i, n - i),
S2.Substring(i, n - i)))
{
return true;
}
// Check if S2[0...i] is a scrambled
// string of S1[n-i...n] and S2[i+1...n]
// is a scramble string of S1[0...n-i-1]
if (isScramble(S1.Substring(0, i),
S2.Substring(n - i, i)) &&
isScramble(S1.Substring(i, n - i),
S2.Substring(0, n - i)))
{
return true;
}
}
// If none of the above
// conditions are satisfied
return false;
}
// Driver code
static void Main()
{
string S1 = "coder";
string S2 = "ocred";
if (isScramble(S1, S2))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
// This code is contributed by divyeshrabadiya07
Javascript
C++
// C++ Program to check if a
// given string is a scrambled
// form of another string
#include
using namespace std;
// map declaration for storing key value pair
// means for storing subproblem result
unordered_map mp;
bool isScramble(string S1, string S2)
{
// Strings of non-equal length
// cant' be scramble strings
if (S1.length() != S2.length()) {
return false;
}
int n = S1.length();
// Empty strings are scramble strings
if (n == 0) {
return true;
}
// Equal strings are scramble strings
if (S1 == S2) {
return true;
}
// Check for the condition of anagram
string copy_S1 = S1, copy_S2 = S2;
sort(copy_S1.begin(), copy_S1.end());
sort(copy_S2.begin(), copy_S2.end());
if (copy_S1 != copy_S2) {
return false;
}
// make key of type string for search in map
string key = (S1 + " " + S2);
// checking if both string are before calculated or not
// if calculated means find in map then return it's
// value
if (mp.find(key) != mp.end()) {
return mp[key];
}
// declaring flag variable to store result
bool flag = false;
for (int i = 1; i < n; i++) {
// Check if S2[0...i] is a scrambled
// string of S1[0...i] and if S2[i+1...n]
// is a scrambled string of S1[i+1...n]
if (isScramble(S1.substr(0, i), S2.substr(0, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(i, n - i))) {
flag = true;
return true;
}
// Check if S2[0...i] is a scrambled
// string of S1[n-i...n] and S2[i+1...n]
// is a scramble string of S1[0...n-i-1]
if (isScramble(S1.substr(0, i), S2.substr(n - i, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(0, n - i))) {
flag = true;
return true;
}
}
// add key & flag value to map (store for future use)
// so next time no required to calculate it again
mp[key] = flag;
// If none of the above conditions are satisfied
return false;
}
// Driver Code
int main()
{
string S1 = "coder";
string S2 = "ocred";
if (isScramble(S1, S2)) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}
Python3
# Declaring unordered map globally
map={}
# Python3 program to check if a
# given string is a scrambled
# form of another string
def isScramble(S1: str, S2: str):
# Strings of non-equal length
# cant' be scramble strings
if len(S1) != len(S2):
return False
n = len(S1)
# Empty strings are scramble strings
if not n:
return True
# Equal strings are scramble strings
if S1 == S2:
return True
# Check for the condition of anagram
if sorted(S1) != sorted(S2):
return False
# Checking if both Substrings are in
# map or are already calculated or not
if(S1+' '+S2 in map):
return map[S1+' '+S2]
# Declaring a flag variable
flag = False
for i in range(1, n):
# Check if S2[0...i] is a scrambled
# string of S1[0...i] and if S2[i+1...n]
# is a scrambled string of S1[i+1...n]
if (isScramble(S1[:i], S2[:i]) and
isScramble(S1[i:], S2[i:])):
flag = True
return True
# Check if S2[0...i] is a scrambled
# string of S1[n-i...n] and S2[i+1...n]
# is a scramble string of S1[0...n-i-1]
if (isScramble(S1[-i:], S2[:i]) and
isScramble(S1[:-i], S2[i:])):
flag = True
return True
# Storing calculated value to map
map[S1+" "+S2] = flag
# If none of the above
# conditions are satisfied
return False
# Driver Code
if __name__ == "__main__":
S1 = "great"
S2 = "rgate"
if (isScramble(S1, S2)):
print("Yes")
else:
print("No")
Yes
动态编程解决方案:可以通过将子字符串的布尔值存储在无序映射中来优化上述递归代码,因此如果必须再次检查相同的子字符串,我们可以轻松地从映射中获取值,而不是执行函数调用。
记忆代码:
C++
// C++ Program to check if a
// given string is a scrambled
// form of another string
#include
using namespace std;
// map declaration for storing key value pair
// means for storing subproblem result
unordered_map mp;
bool isScramble(string S1, string S2)
{
// Strings of non-equal length
// cant' be scramble strings
if (S1.length() != S2.length()) {
return false;
}
int n = S1.length();
// Empty strings are scramble strings
if (n == 0) {
return true;
}
// Equal strings are scramble strings
if (S1 == S2) {
return true;
}
// Check for the condition of anagram
string copy_S1 = S1, copy_S2 = S2;
sort(copy_S1.begin(), copy_S1.end());
sort(copy_S2.begin(), copy_S2.end());
if (copy_S1 != copy_S2) {
return false;
}
// make key of type string for search in map
string key = (S1 + " " + S2);
// checking if both string are before calculated or not
// if calculated means find in map then return it's
// value
if (mp.find(key) != mp.end()) {
return mp[key];
}
// declaring flag variable to store result
bool flag = false;
for (int i = 1; i < n; i++) {
// Check if S2[0...i] is a scrambled
// string of S1[0...i] and if S2[i+1...n]
// is a scrambled string of S1[i+1...n]
if (isScramble(S1.substr(0, i), S2.substr(0, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(i, n - i))) {
flag = true;
return true;
}
// Check if S2[0...i] is a scrambled
// string of S1[n-i...n] and S2[i+1...n]
// is a scramble string of S1[0...n-i-1]
if (isScramble(S1.substr(0, i), S2.substr(n - i, i))
&& isScramble(S1.substr(i, n - i),
S2.substr(0, n - i))) {
flag = true;
return true;
}
}
// add key & flag value to map (store for future use)
// so next time no required to calculate it again
mp[key] = flag;
// If none of the above conditions are satisfied
return false;
}
// Driver Code
int main()
{
string S1 = "coder";
string S2 = "ocred";
if (isScramble(S1, S2)) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}
蟒蛇3
# Declaring unordered map globally
map={}
# Python3 program to check if a
# given string is a scrambled
# form of another string
def isScramble(S1: str, S2: str):
# Strings of non-equal length
# cant' be scramble strings
if len(S1) != len(S2):
return False
n = len(S1)
# Empty strings are scramble strings
if not n:
return True
# Equal strings are scramble strings
if S1 == S2:
return True
# Check for the condition of anagram
if sorted(S1) != sorted(S2):
return False
# Checking if both Substrings are in
# map or are already calculated or not
if(S1+' '+S2 in map):
return map[S1+' '+S2]
# Declaring a flag variable
flag = False
for i in range(1, n):
# Check if S2[0...i] is a scrambled
# string of S1[0...i] and if S2[i+1...n]
# is a scrambled string of S1[i+1...n]
if (isScramble(S1[:i], S2[:i]) and
isScramble(S1[i:], S2[i:])):
flag = True
return True
# Check if S2[0...i] is a scrambled
# string of S1[n-i...n] and S2[i+1...n]
# is a scramble string of S1[0...n-i-1]
if (isScramble(S1[-i:], S2[:i]) and
isScramble(S1[:-i], S2[i:])):
flag = True
return True
# Storing calculated value to map
map[S1+" "+S2] = flag
# If none of the above
# conditions are satisfied
return False
# Driver Code
if __name__ == "__main__":
S1 = "great"
S2 = "rgate"
if (isScramble(S1, S2)):
print("Yes")
else:
print("No")
Yes
时间复杂度: O(N^2),其中 N 是给定字符串的长度。
辅助空间: O(N^2),因为我们需要在我们的 mp 映射中存储 O(N^2)字符串。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。