Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added scramble string algo #1861

Merged
merged 1 commit into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Loading