Skip to content

Commit f6fe36b

Browse files
authored
Merge pull request #1290 from Damini2004/GFG-DSA
GFG-0105-Scrambled String Added
2 parents d9165b1 + 4461cc4 commit f6fe36b

File tree

2 files changed

+275
-0
lines changed

2 files changed

+275
-0
lines changed
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
---
2+
id: Scrambled-String
3+
title: Scrambled-String (Geeks for Geeks)
4+
sidebar_label: Scrambled-String
5+
tags:
6+
- Intermediate
7+
- Geeks for Geeks
8+
- CPP
9+
- Python
10+
- DSA
11+
description: "This is a solution to the Scrambled-String problem on Geeks for Geeks."
12+
---
13+
14+
## Problem Description
15+
16+
Given two strings S1 and S2 of equal length, the task is to determine if S2 is a scrambled form of S1.
17+
18+
Scrambled string: Given string str, we can represent it as a binary tree by partitioning it into two non-empty substrings recursively.
19+
Below is one possible representation of str = coder:
20+
![alt text](image.png)
21+
To scramble the string, we may choose any non-leaf node and swap its two children.
22+
Suppose, we choose the node co and swap its two children, it produces a scrambled string ocder.
23+
Similarly, if we continue to swap the children of nodes der and er, it produces a scrambled string ocred.
24+
25+
Note: Scrambled string is not the same as an Anagram.
26+
Print "Yes" if S2 is a scrambled form of S1 otherwise print "No".
27+
28+
29+
## Examples
30+
31+
**Example:**
32+
33+
Consider the following graph:
34+
35+
```
36+
ocder
37+
/ \
38+
oc der
39+
/ \
40+
o c
41+
```
42+
**Input:** S1="coder", S2="ocder"
43+
**Explanation:** ocder is a scrambled
44+
form of coder.
45+
**Output:** Yes
46+
47+
## Your Task
48+
49+
You don't need to read input or print anything. You only need to complete the function isScramble() which takes two strings S1 and S2 as input and returns a boolean value.
50+
51+
Expected Time Complexity: $O(N2)$.
52+
Expected Auxiliary Space: $O(N2)$.
53+
54+
## Constraints
55+
56+
- S1.length = S2.length
57+
- `S1.length<=31`
58+
- S1 and S2 consist of lower-case English letters.
59+
60+
## Problem Explanation
61+
62+
Here's the step-by-step breakdown of the Scrambled String process:
63+
64+
**Step 1 :** A scrambled string is defined based on recursive partitioning and swapping of substrings. Here’s a more detailed explanation:
65+
66+
**Step 2 :** Binary Tree Representation:Given a string str, you can represent it as a binary tree by recursively partitioning it into two non-empty substrings.
67+
**Step 3 :** For example, for the string "coder": You can split it into "co" and "der".
68+
Each of these can be further split recursively, forming a binary tree structure.
69+
**Step 4 :**Scrambling: A string S2 is a scrambled form of string S1 if S2 can be obtained by swapping the left and right children of some non-leaf nodes in the binary tree representation of S1.
70+
For instance, "coder" can be scrambled to "ocder" by swapping "co" and "der", then further scrambling "co" to "oc".
71+
72+
### Code Implementation
73+
74+
<Tabs>
75+
<TabItem value="Python" label="Python" default>
76+
<SolutionAuthor name="@ngmuraqrdd"/>
77+
```python
78+
class Solution(object):
79+
def isScramble(self, s1, s2):
80+
"""
81+
:type s1: str
82+
:type s2: str
83+
:rtype: bool
84+
"""
85+
# Base cases
86+
87+
n = len(s1)
88+
89+
# If both strings are not equal in size
90+
if len(s2) != n:
91+
return False
92+
93+
# If both strings are equal
94+
if s1 == s2:
95+
return True
96+
97+
# If code is reached to this condition then following this are sure:
98+
# 1. size of both string is equal
99+
# 2. string are not equal
100+
# so size is equal (where size==1) and they are not equal then obviously false
101+
# example 'a' and 'b' size is equal, string are not equal
102+
if n == 1:
103+
return False
104+
105+
key = s1 + " " + s2
106+
107+
# Check if this problem has already been solved
108+
if key in self.mp:
109+
return self.mp[key]
110+
111+
# For every iteration it can two condition
112+
# 1. We should proceed without swapping
113+
# 2. We should swap before looking next
114+
for i in range(1, n):
115+
# ex of without swap: gr|eat and rg|eat
116+
without_swap = (
117+
# Left part of first and second string
118+
self.isScramble(s1[:i], s2[:i])
119+
and
120+
# Right part of first and second string;
121+
self.isScramble(s1[i:], s2[i:])
122+
)
123+
124+
# If without swap gives us the right answer then we do not need
125+
# to call the recursion with swap
126+
if without_swap:
127+
return True
128+
129+
# ex of with swap: gr|eat rge|at
130+
# here we compare "gr" with "at" and "eat" with "rge"
131+
with_swap = (
132+
# Left part of first and right part of second
133+
self.isScramble(s1[:i], s2[n-i:])
134+
and
135+
# Right part of first and left part of second
136+
self.isScramble(s1[i:], s2[:n-i])
137+
)
138+
139+
# If with swap gives us the right answer then we return True
140+
# otherwise, the for loop does its work
141+
if with_swap:
142+
return True
143+
144+
self.mp[key] = False
145+
return False
146+
147+
# for storing already solved problems
148+
mp = {}
149+
```
150+
</TabItem>
151+
152+
<TabItem value="C++" label="C++" default>
153+
<SolutionAuthor name="@ngmuraqrdd"/>
154+
```cpp
155+
class Solution {
156+
public:
157+
//for storing already solved problems
158+
unordered_map<string,bool> mp;
159+
160+
161+
bool isScramble(string s1, string s2) {
162+
//base cases
163+
164+
int n = s1.size();
165+
166+
//if both string are not equal in size
167+
if(s2.size()!=n)
168+
return false;
169+
170+
//if both string are equal
171+
if(s1==s2)
172+
return true;
173+
174+
175+
176+
//if code is reached to this condition then following this are sure:
177+
//1. size of both string is equal
178+
//2. string are not equal
179+
//so size is equal (where size==1) and they are not equal then obviously false
180+
//example 'a' and 'b' size is equal ,string are not equal
181+
if(n==1)
182+
return false;
183+
184+
string key = s1+" "+s2;
185+
186+
//check if this problem has already been solved
187+
if(mp.find(key)!=mp.end())
188+
return mp[key];
189+
190+
//for every iteration it can two condition
191+
//1.we should proceed without swapping
192+
//2.we should swap before looking next
193+
for(int i=1;i<n;i++)
194+
{
195+
196+
//ex of without swap: gr|eat and rg|eat
197+
bool withoutswap = (
198+
//left part of first and second string
199+
isScramble(s1.substr(0,i),s2.substr(0,i))
200+
201+
&&
202+
203+
//right part of first and second string;
204+
isScramble(s1.substr(i),s2.substr(i))
205+
);
206+
207+
208+
209+
//if without swap give us right answer then we do not need
210+
//to call the recursion withswap
211+
if(withoutswap)
212+
return true;
213+
214+
//ex of withswap: gr|eat rge|at
215+
//here we compare "gr" with "at" and "eat" with "rge"
216+
bool withswap = (
217+
//left part of first and right part of second
218+
isScramble(s1.substr(0,i),s2.substr(n-i))
219+
220+
&&
221+
222+
//right part of first and left part of second
223+
isScramble(s1.substr(i),s2.substr(0,n-i))
224+
);
225+
226+
227+
228+
//if withswap give us right answer then we return true
229+
//otherwise the for loop do it work
230+
if(withswap)
231+
return true;
232+
//we are not returning false in else case
233+
//because we want to check further cases with the for loop
234+
}
235+
236+
237+
return mp[key] = false;
238+
239+
}
240+
};
241+
```
242+
</TabItem>
243+
</Tabs>
244+
245+
## Solution Logic
246+
247+
**1.Base Cases:**If the lengths of the two strings are not equal, they cannot be scrambled forms of each other, so return false.
248+
If the two strings are identical, they are trivially scrambled forms of each other, so return true.
249+
If the length of the string is 1 and the strings are not equal, return false.
250+
**2.Memoization:** Use a map mp to store already solved subproblems to avoid redundant computations.
251+
The key for the map is a combination of the two strings, represented as s1 + " " + s2.
252+
**3.Recursive Check:** Iterate over possible split points of the strings.
253+
For each split point, there are two cases to consider:
254+
1.Without swapping:
255+
Compare the left part of s1 with the left part of s2 and the right part of s1 with the right part of s2.
256+
2.With swapping:
257+
Compare the left part of s1 with the right part of s2 and the right part of s1 with the left part of s2.
258+
**4.Return Result:** If either of the conditions (with or without swapping) is satisfied, return true.
259+
If none of the conditions are satisfied after checking all possible split points, store the result as false in the memoization map and return false.1.
260+
261+
## Time Complexity
262+
263+
$O(N2)$.
264+
265+
## Space Complexity
266+
267+
$O(N2)$.
268+
269+
## Resources
270+
271+
- **GFG Problem:** [GFG Problem](https://www.geeksforgeeks.org/problems/scrambled-string/1)
272+
- **LeetCode Problem:** [LeetCode Problem](https://leetcode.com/problems/scramble-string/description/)
273+
- **Author's Geeks for Geeks Profile:** | [DaminiChachane](https://leetcode.com/u/divcxl15/) |
274+
275+
This format ensures that all necessary details about the problem and its solution are clearly presented and easy to follow.
Loading

0 commit comments

Comments
 (0)