Bird
Raised Fist0
DSA Cprogramming

Word Break Problem in DSA C

Choose your learning style10 modes available
Mental Model
We want to check if a string can be split into valid words from a dictionary. We try breaking the string at every position and see if the left part is a word and the right part can also be split.
Analogy: Imagine you have a long sentence without spaces and a list of known words. You try to put spaces in different places to see if the sentence can be made up of those known words.
string: w o r d b r e a k
dictionary: [word, break, problem]

Initial:
"wordbreak"

Try splits:
[word] + [break]
[wordb] + [reak]
[wordbr] + [eak]
...
Dry Run Walkthrough
Input: string: "wordbreak", dictionary: ["word", "break", "problem"]
Goal: Determine if "wordbreak" can be segmented into dictionary words
Step 1: Check prefix "w" - not in dictionary, move to next prefix
"w" (not word), continue checking prefixes
Step 2: Check prefix "wo" - not in dictionary, move to next prefix
"wo" (not word), continue checking prefixes
Step 3: Check prefix "wor" - not in dictionary, move to next prefix
"wor" (not word), continue checking prefixes
Step 4: Check prefix "word" - found in dictionary, now check suffix "break"
"word" (word), suffix "break" to check
Step 5: Check suffix "break" - found in dictionary, so "wordbreak" can be segmented
"word" + "break" both words, success
Result:
"word" -> "break" -> null (string can be segmented)
Annotated Code
DSA C
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

// Check if word is in dictionary
bool isInDict(const char* word, const char* dict[], int dictSize) {
    for (int i = 0; i < dictSize; i++) {
        if (strcmp(word, dict[i]) == 0) {
            return true;
        }
    }
    return false;
}

// Word Break function using recursion and memoization
bool wordBreakHelper(const char* s, const char* dict[], int dictSize, int start, int memo[]) {
    int len = strlen(s);
    if (start == len) {
        return true; // reached end successfully
    }
    if (memo[start] != -1) {
        return memo[start]; // return cached result
    }
    for (int end = start + 1; end <= len; end++) {
        int subLen = end - start;
        char sub[subLen + 1];
        strncpy(sub, s + start, subLen);
        sub[subLen] = '\0';
        if (isInDict(sub, dict, dictSize)) {
            if (wordBreakHelper(s, dict, dictSize, end, memo)) {
                memo[start] = 1;
                return true;
            }
        }
    }
    memo[start] = 0;
    return false;
}

bool wordBreak(const char* s, const char* dict[], int dictSize) {
    int len = strlen(s);
    int memo[len];
    for (int i = 0; i < len; i++) {
        memo[i] = -1; // -1 means not computed
    }
    return wordBreakHelper(s, dict, dictSize, 0, memo);
}

int main() {
    const char* dict[] = {"word", "break", "problem"};
    const char* s = "wordbreak";
    if (wordBreak(s, dict, 3)) {
        printf("word break possible\n");
    } else {
        printf("word break not possible\n");
    }
    return 0;
}
if (start == len) { return true; }
base case: reached end means successful segmentation
if (memo[start] != -1) { return memo[start]; }
use memo to avoid repeated work
for (int end = start + 1; end <= len; end++) { ... }
try all prefixes from current start
if (isInDict(sub, dict, dictSize)) { if (wordBreakHelper(...)) { memo[start] = true; return true; } }
if prefix is word and suffix can be segmented, mark true and return
memo[start] = false; return false;
no valid segmentation found from this start
OutputSuccess
word break possible
Complexity Analysis
Time: O(n^3) because for each start index we try all end indices and substring copying takes O(n)
Space: O(n) for memoization array to store results for each start index
vs Alternative: Naive recursion without memoization is exponential because it recomputes subproblems many times
Edge Cases
empty string
returns true because empty string can be segmented trivially
DSA C
if (start == len) { return true; }
string with no matching dictionary words
returns false as no segmentation possible
DSA C
memo[start] = false; return false;
string equals a dictionary word
returns true immediately
DSA C
if (start == len) { return true; }
When to Use This Pattern
When you need to check if a string can be split into valid dictionary words, use the Word Break pattern with recursion and memoization to efficiently explore all splits.
Common Mistakes
Mistake: Not using memoization causing exponential time and timeout
Fix: Add a memo array to store results for each start index and reuse them
Mistake: Not checking the base case when start reaches string length
Fix: Add base case: if start == length, return true
Mistake: Incorrect substring extraction causing wrong comparisons
Fix: Use strncpy carefully and null-terminate substring before dictionary check
Summary
Checks if a string can be split into dictionary words by trying all prefixes and recursively checking suffixes.
Use when you want to validate if a string can be segmented into known words.
The key insight is to try every prefix and remember results to avoid repeated work.

Practice

(1/5)
1. What does the Word Break Problem ask you to determine about a given string s and a dictionary of words wordDict?
easy
A. If s contains any substring from wordDict
B. If s can be segmented into a space-separated sequence of one or more dictionary words
C. If s is exactly equal to any word in wordDict
D. If s is a palindrome

Solution

  1. Step 1: Understand the problem statement

    The Word Break Problem asks if the entire string s can be split into parts where each part is a word in the dictionary.
  2. Step 2: Compare options with the problem

    If s can be segmented into a space-separated sequence of one or more dictionary words correctly describes this segmentation into dictionary words. Other options describe different checks.
  3. Final Answer:

    If s can be segmented into a space-separated sequence of one or more dictionary words -> Option B
  4. Quick Check:

    Word Break Problem = segmentation check [OK]
Hint: Remember: Word Break means full segmentation into dictionary words [OK]
Common Mistakes:
  • Thinking it checks for substring presence only
  • Confusing exact match with segmentation
  • Assuming palindrome check
2. Which of the following C code snippets correctly declares a function prototype for solving the Word Break Problem?
easy
A. int wordBreak(char s[], char *wordDict[], int wordDictSize);
B. void wordBreak(char s[], char wordDict[], int size);
C. int wordBreak(char *s, char *wordDict, int wordDictSize);
D. int wordBreak(char **s, char **wordDict, int wordDictSize);

Solution

  1. Step 1: Understand parameter types for the Word Break function

    The string s is a character array, so char s[] or char *s works. The dictionary is an array of strings, so char *wordDict[] is correct. The size is an integer.
  2. Step 2: Check each option

    int wordBreak(char s[], char *wordDict[], int wordDictSize); matches the correct signature: int wordBreak(char s[], char *wordDict[], int wordDictSize); int wordBreak(char *s, char *wordDict, int wordDictSize); uses char *wordDict which is incorrect for array of strings. void wordBreak(char s[], char wordDict[], int size); uses char wordDict[] which is incorrect for array of strings. int wordBreak(char **s, char **wordDict, int wordDictSize); uses char **s which is incorrect for a single string.
  3. Final Answer:

    int wordBreak(char s[], char *wordDict[], int wordDictSize); -> Option A
  4. Quick Check:

    Function prototype with string and array of strings = int wordBreak(char s[], char *wordDict[], int wordDictSize); [OK]
Hint: Dictionary is array of strings: use char *wordDict[] [OK]
Common Mistakes:
  • Using char wordDict[] instead of array of strings
  • Using char **s for input string
  • Wrong return type or missing parameters
3. What will be the output of the following C code snippet for the Word Break Problem?
char *dict[] = {"leet", "code"};
int result = wordBreak("leetcode", dict, 2);
printf("%d", result);
Assuming wordBreak returns 1 if segmentation is possible, else 0.
medium
A. 1
B. 0
C. Compilation error
D. Runtime error

Solution

  1. Step 1: Analyze the input string and dictionary

    The string is "leetcode" and dictionary contains "leet" and "code".
  2. Step 2: Check if string can be segmented

    "leetcode" can be split as "leet" + "code", both in dictionary, so segmentation is possible.
  3. Final Answer:

    1 -> Option A
  4. Quick Check:

    "leetcode" segmented as "leet" + "code" = 1 [OK]
Hint: Check if string splits fully into dictionary words [OK]
Common Mistakes:
  • Assuming partial match is enough
  • Confusing return values
  • Ignoring dictionary contents
4. Identify the error in the following C code snippet for the Word Break Problem:
int wordBreak(char *s, char **wordDict, int wordDictSize) {
    int len = strlen(s);
    int dp[len+1];
    dp[0] = 1;
    for (int i = 1; i <= len; i++) {
        dp[i] = 0;
        for (int j = 0; j < i; j++) {
            if (dp[j] && strncmp(s+j, wordDict[i], i-j) == 0) {
                dp[i] = 1;
                break;
            }
        }
    }
    return dp[len];
}
medium
A. Missing return statement
B. dp array not initialized properly
C. Using wordDict[i] instead of wordDict[j] in strncmp
D. Loop indices are out of range

Solution

  1. Step 1: Understand the nested loop and string comparison

    The inner loop checks substrings from index j to i. It should compare with wordDict[j], not wordDict[i].
  2. Step 2: Identify the incorrect array index usage

    Using wordDict[i] is wrong because i goes up to length of s, which may exceed wordDictSize and is unrelated to dictionary indexing.
  3. Final Answer:

    Using wordDict[i] instead of wordDict[j] in strncmp -> Option C
  4. Quick Check:

    Index in dictionary should match substring start index [OK]
Hint: Check indices used for dictionary access in loops [OK]
Common Mistakes:
  • Mixing loop variables for dictionary access
  • Not initializing dp array correctly
  • Ignoring return statement
5. Given the string s = "applepenapple" and dictionary wordDict = ["apple", "pen"], which approach correctly solves the Word Break Problem using dynamic programming in C?
hard
A. Use recursion without memoization to check all substring splits
B. Use a stack to store all dictionary words and pop when matched
C. Sort the dictionary and check if s starts with any word
D. Use a boolean dp array where dp[i] is true if s[0..i-1] can be segmented, then check all substrings ending at i

Solution

  1. Step 1: Understand dynamic programming approach

    We create a boolean dp array where dp[i] is true if substring s[0..i-1] can be segmented into dictionary words.
  2. Step 2: Check all substrings ending at each position

    For each position i, check all j < i where dp[j] is true and substring s[j..i-1] is in dictionary. If yes, set dp[i] true.
  3. Step 3: Return dp[length of s]

    If dp at the end is true, the string can be segmented.
  4. Final Answer:

    Use a boolean dp array where dp[i] is true if s[0..i-1] can be segmented, then check all substrings ending at i -> Option D
  5. Quick Check:

    DP boolean array with substring checks = Use a boolean dp array where dp[i] is true if s[0..i-1] can be segmented, then check all substrings ending at i [OK]
Hint: Use dp array to track segmentation up to each index [OK]
Common Mistakes:
  • Using recursion without memo causing timeout
  • Sorting dictionary does not help segmentation
  • Stack approach is incorrect for this problem
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard