Skip to content

Commit

Permalink
added scramble string algo
Browse files Browse the repository at this point in the history
  • Loading branch information
NK-Works authored Nov 10, 2024
1 parent 0cb932e commit b6bb632
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
35 changes: 35 additions & 0 deletions Dynamic Programming/Scramble String/README.md
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.
60 changes: 60 additions & 0 deletions Dynamic Programming/Scramble String/program.c
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;
}

0 comments on commit b6bb632

Please sign in to comment.