LeetCode 139. Word Break

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".



I made a mistake about backtracking the string. My first version was as follows:

bool wordBreak(string s, int pos, unordered_set<string>& wordDict) {
    if(pos >= s.size()) {return true;}
    for(int i = pos + 1; i <= s.size(); ++i) {
        string tmp = s.substr(pos, i - pos);
        if(wordDict.find(tmp) != wordDict.end()) {
            wordBreak(s, i, wordDict);
        }
    }
}
Actually this is not correct. Suppose the wordDict is "leet" "code". The string s : leetcode.

the first loop will match, leet; then pushed onto stack. The recursion for will go to "code". This should return true. But since this is recursion, it will go back to the first loop again, then return false. String recursion should set a flag. Once the flag went to true, it should always just return without  changing the flag anymore.


#include <string>
#include <unordered_set>
#include <iostream>
#include <vector>
using namespace std;

//Recursion
void wordBreak(string s, int pos, unordered_set<string>& wordDict, bool& found) {
    if(found) return;
    if(pos >= s.size()) {found = true; return;}
    for(int i = pos + 1; i <= s.size(); ++i) {
        string tmp = s.substr(pos, i - pos);
        if(wordDict.find(tmp) != wordDict.end()) {
            wordBreak(s, i, wordDict, found);
        }
    }
 }

// DP method
bool wordBreakII(string s, unordered_set<string>& wordDict) {
    if(s.size() == 0) return true;
    vector<int> dp(s.size(), 0);
    for(int i = 0; i < s.size(); ++i) {
        for(int j = 0; j <= i; ++j) {
            if((!j || dp[j-1]) && (wordDict.find(s.substr(j, i - j + 1)) != wordDict.end())) {
                dp[i] = 1;
                break;
            }
        }
    }
    return dp[s.size() - 1];
}

bool wordBreak(string s, unordered_set<string>& wordDict) {
    int pos = 0;
    bool found = false;
    wordBreak(s, pos, wordDict, found);
    if(found) return true;
}

int main(void) {
    unordered_set<string> wordDict;
    wordDict.insert("aaaa");
    wordDict.insert("aaa");
    cout << wordBreakII("aaaaaaa", wordDict) << endl;
}
~


你可能感兴趣的:(LeetCode 139. Word Break)