-
Notifications
You must be signed in to change notification settings - Fork 303
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Scramble String Problem | ||
|
||
## Description | ||
|
||
The Scramble String problem is to determine whether one string is a scrambled version of another. Given two strings, `s1` and `s2`, we say that `s2` is a scrambled version of `s1` if it can be formed by recursively dividing `s1` into two non-empty substrings and swapping them. | ||
|
||
For example: | ||
- Input: `s1 = "great"`, `s2 = "rgeat"` | ||
- Output: `true` (because "rgeat" is a scrambled version of "great") | ||
|
||
## Problem Requirements | ||
|
||
We need to: | ||
1. Check if two strings contain the same characters. | ||
2. Recursively verify if substrings can be swapped to form the scrambled string. | ||
3. Optimize using memoization to avoid redundant calculations. | ||
|
||
## Solution Approach | ||
|
||
This solution uses **Dynamic Programming** with **Recursion and Memoization**: | ||
|
||
1. **Recursive Check**: | ||
- For each possible split of `s1`, we recursively check: | ||
- If dividing and not swapping substrings forms `s2`, or | ||
- If dividing and swapping substrings forms `s2`. | ||
|
||
2. **Memoization Table**: | ||
- We use a 3D table `memo[i1][i2][len]` to store results of subproblems where: | ||
- `i1` and `i2` are starting indices in `s1` and `s2`. | ||
- `len` is the length of the substrings. | ||
- Each entry in the table can be either `-1` (not calculated), `1` (scramble), or `0` (not a scramble). | ||
|
||
3. **Complexity**: | ||
- **Time Complexity**: `O(N^4)`, where `N` is the length of the string. | ||
- **Space Complexity**: `O(N^3)` due to the memoization table. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <string.h> | ||
|
||
#define MAX_LEN 100 | ||
|
||
// Memoization table to store results | ||
int memo[MAX_LEN][MAX_LEN][MAX_LEN]; | ||
|
||
// Helper function to check if two strings have the same characters | ||
bool haveSameCharacters(const char *s1, const char *s2, int len) { | ||
int count[26] = {0}; | ||
for (int i = 0; i < len; i++) { | ||
count[s1[i] - 'a']++; | ||
count[s2[i] - 'a']--; | ||
} | ||
for (int i = 0; i < 26; i++) { | ||
if (count[i] != 0) return false; | ||
} | ||
return true; | ||
} | ||
|
||
// Recursive function with memoization to check if s2 is a scrambled version of s1 | ||
bool isScramble(const char *s1, const char *s2, int i1, int i2, int len) { | ||
if (memo[i1][i2][len] != -1) return memo[i1][i2][len]; | ||
|
||
if (strncmp(s1 + i1, s2 + i2, len) == 0) return memo[i1][i2][len] = 1; | ||
|
||
if (!haveSameCharacters(s1 + i1, s2 + i2, len)) return memo[i1][i2][len] = 0; | ||
|
||
for (int i = 1; i < len; i++) { | ||
if ((isScramble(s1, s2, i1, i2, i) && isScramble(s1, s2, i1 + i, i2 + i, len - i)) || | ||
(isScramble(s1, s2, i1, i2 + len - i, i) && isScramble(s1, s2, i1 + i, i2, len - i))) { | ||
return memo[i1][i2][len] = 1; | ||
} | ||
} | ||
|
||
return memo[i1][i2][len] = 0; | ||
} | ||
|
||
bool isScrambleWrapper(const char *s1, const char *s2) { | ||
int len = strlen(s1); | ||
if (len != strlen(s2)) return false; | ||
|
||
memset(memo, -1, sizeof(memo)); | ||
return isScramble(s1, s2, 0, 0, len); | ||
} | ||
|
||
int main() { | ||
const char *s1 = "great"; | ||
const char *s2 = "rgeat"; | ||
|
||
if (isScrambleWrapper(s1, s2)) { | ||
printf("'%s' is a scrambled version of '%s'\n", s2, s1); | ||
} else { | ||
printf("'%s' is NOT a scrambled version of '%s'\n", s2, s1); | ||
} | ||
|
||
return 0; | ||
} |