[LeetCode] Word Break

The typical solution to this problem is to use Dynamic Programming. The state dp[i] represents whether s[0..i - 1] can be broken into words in wordDict and the state equation is:

dp[i] = true, if there exists j < i such that dp[j] = true and s.substr(j, i - j) is in wordDict

dp[i] = false, otherwise.

The code is as follows (we use minlen and maxlen to reduce the number of checks).

 1 class Solution {
 2 public:
 3     bool wordBreak(string s, unordered_set<string>& wordDict) {
 4         int n = s.length();
 5         vector<bool> dp(n + 1, false);
 6         dp[0] = true;
 7         for (string word : wordDict) {
 8             minlen = min(minlen, (int)word.length());
 9             maxlen = max(maxlen, (int)word.length());
10         }
11         for (int i = 1; i <= n; i++) {
12             for (int j = i - minlen; j >= max(0, j - maxlen); j--) {
13                 if (dp[j] && wordDict.find(s.substr(j, i - j)) != wordDict.end()) {
14                     dp[i] = true;
15                     break;
16                 }
17             }
18         }
19         return dp[n];
20     }
21 private:
22     int minlen, maxlen;
23 };

This problem can also be solved using DFS or BFS.

DFS:

 1 class Solution {
 2 public:
 3     bool wordBreak(string s, unordered_set<string>& wordDict) {
 4         for (string word : wordDict) {
 5             minlen = min(minlen, (int)word.length());
 6             maxlen = max(maxlen, (int)word.length());
 7         }
 8         unordered_map<string, bool> records;
 9         return wordBreakDFS(s, 0, wordDict, records);
10     }
11 private:
12     int minlen, maxlen;
13     bool wordBreakDFS(string& s, int idx, unordered_set<string>& wordDict, unordered_map<string, bool>& records) {
14         int n = s.length();
15         if (idx == n) return true;
16         string tail = s.substr(idx, n - idx);
17         if (records.find(tail) != records.end())
18             return records[tail];
19         for (int i = idx + minlen; i <= min(idx + maxlen, n); i++) {
20             string part = s.substr(idx, i - idx);
21             if (wordDict.find(part) != wordDict.end() && wordBreakDFS(s, i, wordDict, records))
22                 return records[part] = true;
23         }
24         return records[tail] = false;
25     }
26 };

BFS:

 1 class Solution {
 2 public:
 3     bool wordBreak(string s, unordered_set<string>& wordDict) {
 4         int n = s.length();
 5         for (string word : wordDict) {
 6             minlen = min(minlen, (int)word.length());
 7             maxlen = max(maxlen, (int)word.length());
 8         }
 9         queue<int> toVisit;
10         unordered_set<int> visited;
11         toVisit.push(0);
12         while (!toVisit.empty()) {
13             int start = toVisit.front();
14             toVisit.pop();
15             if (visited.find(start) == visited.end()) {
16                 visited.insert(start);
17                 for (int end = start + minlen - 1; end < min(start + maxlen, n); end++) {
18                     string part = s.substr(start, end - start + 1);
19                     if (wordDict.find(part) != wordDict.end()) {
20                         if (end + 1 == n) return true;
21                         toVisit.push(end + 1);
22                     }
23                 }
24             }
25         }
26         return false;
27     }
28 private:
29     int minlen, maxlen;
30 };

 

posted @ 2015-07-02 11:48  jianchao-li  阅读(268)  评论(0编辑  收藏  举报