We can scramble a string s to get a string t using the following algorithm:
s
, divide it to x
and y
where s = x + y
.s
may become s = x + y
or s = y + x
.x
and y
.Given two strings s1
and s2
of the same length, return true
if s2
is a scrambled string of s1
, otherwise, return false
.
Example 1:
Input: s1 = "great", s2 = "rgeat" Output: true Explanation: One possible scenario applied on s1 is: "great" --> "gr/eat" // divide at random index. "gr/eat" --> "gr/eat" // random decision is not to swap the two substrings and keep them in order. "gr/eat" --> "g/r / e/at" // apply the same algorithm recursively on both substrings. divide at random index each of them. "g/r / e/at" --> "r/g / e/at" // random decision was to swap the first substring and to keep the second substring in the same order. "r/g / e/at" --> "r/g / e/ a/t" // again apply the algorithm recursively, divide "at" to "a/t". "r/g / e/ a/t" --> "r/g / e/ a/t" // random decision is to keep both substrings in the same order. The algorithm stops now, and the result string is "rgeat" which is s2. As one possible scenario led s1 to be scrambled to s2, we return true.
Example 2:
Input: s1 = "abcde", s2 = "caebd" Output: false
Example 3:
Input: s1 = "a", s2 = "a" Output: true
Constraints:
s1.length == s2.length
1 <= s1.length <= 30
s1
and s2
consist of lowercase English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force approach to determine if one string is a scrambled version of another involves exploring every possible way to cut and rearrange the first string. We essentially generate all possible scrambled versions of the first string and then check if any of these match the second string. If even one match is found, we know they are scrambled versions of each other.
Here's how the algorithm would work step-by-step:
def is_scramble_string_brute_force(string1, string2):
if len(string1) != len(string2):
return False
if string1 == string2:
return True
if sorted(string1) != sorted(string2):
return False
string_length = len(string1)
# Iterate through all possible split points
for i in range(1, string_length):
#Consider no swap
if (is_scramble_string_brute_force(string1[:i], string2[:i]) and\
is_scramble_string_brute_force(string1[i:], string2[i:])):
return True
#Consider swap
#This checks if a scramble exists.
if (is_scramble_string_brute_force(string1[:i], string2[string_length-i:]) and\
is_scramble_string_brute_force(string1[i:], string2[:string_length-i])):
return True
return False
The goal is to figure out if one string can be rearranged to look like another by swapping parts of it. The best way to do this is to check if breaking both strings into smaller identical parts is possible, because if you can break them into equivalent smaller pieces, it means they're scrambled versions of each other.
Here's how the algorithm would work step-by-step:
def is_scramble(first_string, second_string):
if len(first_string) != len(second_string):
return False
if sorted(first_string) != sorted(second_string):
return False
string_length = len(first_string)
if string_length <= 3:
return sorted(first_string) == sorted(second_string)
for i in range(1, string_length):
# Check both possibilities: swap or no swap.
if (is_scramble(first_string[:i], second_string[:i]) and\
is_scramble(first_string[i:], second_string[i:])):
return True
# Here, we're checking the swapped possibility
if (is_scramble(first_string[:i], second_string[string_length - i:]) and\
is_scramble(first_string[i:], second_string[:string_length - i])):
return True
return False
Case | How to Handle |
---|---|
Null or empty strings s1 or s2 | Return true if both are null/empty, false if one is null/empty while the other is not; otherwise, throw IllegalArgumentException. |
Strings s1 and s2 have different lengths | Return false immediately, as scrambled strings must have equal length. |
Strings s1 and s2 are equal | Return true immediately, as identical strings are trivially scrambled versions of each other. |
Strings s1 and s2 have different character counts | Return false if character counts differ, as any scrambling preserves character counts. |
Strings with very long length leading to stack overflow during recursive calls. | Consider using a DP approach instead of recursion to avoid stack overflow errors. |
String containing only 1 character. | Return true if both strings have same single character, false otherwise. |
Very deep recursion calls due to string characteristics. | Memoize intermediate results (subproblems) to avoid redundant calculations and improve performance. |
Integer overflow when calculating string hash values (if using hashing for comparison). | Use modulo operator with a large prime number or choose a hashing algorithm that avoids overflow. |