Bird
Raised Fist0
DSA C++programming

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 similarly.
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 only.
s = "leetcode"
Dictionary = {"leet", "code"}

[ l e e t c o d e ]
 ↑ start

Try splitting:
[leet] + [code]
Both in dictionary -> success
Dry Run Walkthrough
Input: string: "leetcode", dictionary: ["leet", "code"]
Goal: Determine if "leetcode" can be segmented into dictionary words
Step 1: Check prefix "l" if in dictionary
[l] e e t c o d e
Dictionary check: no
Why: We try smallest prefix to find a valid word
Step 2: Check prefix "le" if in dictionary
[le] e t c o d e
Dictionary check: no
Why: Continue checking longer prefixes
Step 3: Check prefix "lee" if in dictionary
[lee] t c o d e
Dictionary check: no
Why: Still no match, try next
Step 4: Check prefix "leet" if in dictionary
[leet] c o d e
Dictionary check: yes
Why: Found a valid word, now check suffix "code"
Step 5: Recursively check suffix "code"
c o d e
Try prefixes: "c", "co", "cod", "code"
Why: We repeat the same process for the remaining string
Step 6: Check prefix "code" if in dictionary
[code]
Dictionary check: yes
Why: Suffix is a valid word, so whole string can be segmented
Result:
[leet] -> [code] -> null
Answer: true
Annotated Code
DSA C++
#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>

using namespace std;

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> dict(wordDict.begin(), wordDict.end());
        vector<bool> dp(s.size() + 1, false);
        dp[0] = true; // empty string can be segmented

        for (int i = 1; i <= s.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && dict.find(s.substr(j, i - j)) != dict.end()) {
                    dp[i] = true; // mark substring s[0..i-1] as segmentable
                    break; // no need to check further splits
                }
            }
        }
        return dp[s.size()];
    }
};

int main() {
    Solution sol;
    string s = "leetcode";
    vector<string> wordDict = {"leet", "code"};
    bool result = sol.wordBreak(s, wordDict);
    cout << (result ? "true" : "false") << endl;
    return 0;
}
dp[0] = true; // empty string can be segmented
Initialize base case: empty string is always segmentable
for (int i = 1; i <= s.size(); i++) {
Check all substring lengths from 1 to full string length
for (int j = 0; j < i; j++) {
Try all possible splits of substring s[0..i-1]
if (dp[j] && dict.find(s.substr(j, i - j)) != dict.end()) {
If prefix s[0..j-1] is segmentable and suffix s[j..i-1] is a word, mark dp[i]
dp[i] = true; // mark substring s[0..i-1] as segmentable
Mark current substring as segmentable
break; // no need to check further splits
Stop checking splits once segmentable found
return dp[s.size()];
Return if full string is segmentable
OutputSuccess
true
Complexity Analysis
Time: O(n^2) because we check all substring splits for string length n
Space: O(n) for dp array storing segmentable states for substrings
vs Alternative: Naive recursion without memoization is exponential; DP reduces it to polynomial time
Edge Cases
Empty string input
Returns true because empty string can be segmented trivially
DSA C++
dp[0] = true; // empty string can be segmented
String with no valid segmentation
Returns false after checking all splits
DSA C++
return dp[s.size()];
Dictionary contains single character words
Algorithm still works by checking all splits
DSA C++
if (dp[j] && dict.find(s.substr(j, i - j)) != dict.end())
When to Use This Pattern
When asked if a string can be split into dictionary words, use dynamic programming to check all prefixes efficiently.
Common Mistakes
Mistake: Not initializing dp[0] to true, causing all checks to fail
Fix: Set dp[0] = true to represent empty string segmentation
Mistake: Checking substrings incorrectly with wrong indices
Fix: Use s.substr(j, i - j) to get substring from j to i-1
Summary
Checks if a string can be segmented into valid dictionary words.
Use when you need to verify if a sentence without spaces can be split into known words.
The key insight is to use dynamic programming to remember which prefixes can be segmented.

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 is exactly equal to one of the words in wordDict
B. If s contains any substring from wordDict
C. If s can be segmented into a space-separated sequence of one or more dictionary words
D. If s is a palindrome formed by dictionary words

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 from the dictionary wordDict.
  2. Step 2: Differentiate from similar concepts

    It is not enough for s to contain a dictionary word or be equal to one; the whole string must be fully segmented into dictionary words.
  3. Final Answer:

    If s can be segmented into a sequence of dictionary words -> Option C
  4. Quick Check:

    Word Break = Full segmentation check [OK]
Hint: Check if full string splits into dictionary words [OK]
Common Mistakes:
  • Thinking partial substring match is enough
  • Confusing exact match with segmentation
  • Ignoring the order of words in segmentation
2. Which of the following is the correct C++ syntax to declare a function named wordBreak that takes a string s and a vector<string> named wordDict and returns a bool?
easy
A. bool wordBreak(string s, vector<string> &wordDict);
B. bool wordBreak(string s, vector<string>& wordDict);
C. bool wordBreak(string s, vector<string> wordDict);
D. bool wordBreak(string s, vector<string> wordDict&);

Solution

  1. Step 1: Understand parameter passing in C++

    Passing vector<string> by reference requires the ampersand & after the type, with optional space before the variable name.
  2. Step 2: Check syntax correctness

    bool wordBreak(string s, vector<string> &wordDict); correctly places the ampersand before the parameter name with a space: vector<string> &wordDict. bool wordBreak(string s, vector<string>& wordDict); is also valid but less common spacing. bool wordBreak(string s, vector<string> wordDict&); is invalid syntax.
  3. Final Answer:

    bool wordBreak(string s, vector<string> &wordDict); -> Option A
  4. Quick Check:

    Reference parameter syntax = bool wordBreak(string s, vector<string> &wordDict); [OK]
Hint: Ampersand & goes between type and variable name [OK]
Common Mistakes:
  • Placing & after variable name incorrectly
  • Missing semicolon at function declaration
  • Using invalid syntax like wordDict&
3. What is the output of the following C++ code snippet?
bool wordBreak(string s, vector<string> &wordDict) {
    unordered_set<string> dict(wordDict.begin(), wordDict.end());
    vector<bool> dp(s.size() + 1, false);
    dp[0] = true;
    for (int i = 1; i <= s.size(); i++) {
        for (int j = 0; j < i; j++) {
            if (dp[j] && dict.count(s.substr(j, i - j))) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[s.size()];
}

int main() {
    string s = "leetcode";
    vector<string> wordDict = {"leet", "code"};
    cout << (wordBreak(s, wordDict) ? "true" : "false") << endl;
    return 0;
}
medium
A. true
B. false
C. Compilation error
D. Runtime error

Solution

  1. Step 1: Understand the dynamic programming logic

    The code uses a boolean vector dp where dp[i] is true if substring s[0..i-1] can be segmented into dictionary words. It initializes dp[0] as true (empty string).
  2. Step 2: Trace the example input "leetcode" with dictionary ["leet", "code"]

    At i=4, substring "leet" is in dictionary, so dp[4] = true. At i=8, substring "code" is in dictionary and dp[4] is true, so dp[8] = true. Finally, dp[s.size()] = true.
  3. Final Answer:

    true -> Option A
  4. Quick Check:

    DP segmentation confirms full string = true [OK]
Hint: Check dp array for full string index true [OK]
Common Mistakes:
  • Confusing substring indices
  • Forgetting to break inner loop after true
  • Misunderstanding dp initialization
4. Identify the bug in the following C++ code for the Word Break Problem:
bool wordBreak(string s, vector<string> &wordDict) {
    unordered_set<string> dict(wordDict.begin(), wordDict.end());
    vector<bool> dp(s.size(), false);
    dp[0] = true;
    for (int i = 1; i <= s.size(); i++) {
        for (int j = 0; j < i; j++) {
            if (dp[j] && dict.count(s.substr(j, i - j))) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[s.size()];
}
medium
A. dp[0] should be initialized to false
B. dp vector size should be s.size() + 1, not s.size()
C. The substring indices in s.substr are incorrect
D. unordered_set should be a vector instead

Solution

  1. Step 1: Check dp vector size and indexing

    The dp vector is sized to s.size(), but the code accesses dp[s.size()] which is out of bounds. It should be sized s.size() + 1 to include the base case for empty substring.
  2. Step 2: Verify other parts

    unordered_set usage and substring indices are correct. dp[0] must be true to represent empty string segmentation.
  3. Final Answer:

    dp vector size should be s.size() + 1, not s.size() -> Option B
  4. Quick Check:

    dp size off by one causes runtime error [OK]
Hint: dp size = string length + 1 for base case [OK]
Common Mistakes:
  • Using dp size equal to string length only
  • Misinitializing dp[0] to false
  • Confusing substring parameters
5. Given the string s = "applepenapple" and dictionary wordDict = ["apple", "pen"], which of the following modifications to the Word Break algorithm allows it to also return the actual segmented sentence "apple pen apple" instead of just true or false?
hard
A. Use a stack to store indices and print words in reverse order after DP
B. Return the count of possible segmentations instead of a boolean
C. Modify the dictionary to include spaces between words
D. Use a vector of strings to store sentences at each index and build them during DP

Solution

  1. Step 1: Understand the limitation of boolean DP

    The standard Word Break DP returns only true/false indicating if segmentation is possible, but does not store the actual segmented sentences.
  2. Step 2: Modify DP to store sentences

    By using a vector of strings at each dp index, we can store all possible sentences formed up to that index. When a valid word is found, append it to sentences from previous indices.
  3. Step 3: Final answer

    This approach allows reconstructing the segmented sentence like "apple pen apple".
  4. Final Answer:

    Use a vector of strings to store sentences at each index and build them during DP -> Option D
  5. Quick Check:

    Store sentences in DP to reconstruct output [OK]
Hint: Store sentences in DP array to reconstruct segmentation [OK]
Common Mistakes:
  • Trying to modify dictionary words
  • Returning count instead of sentences
  • Using stack without DP sentence storage
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