Question
http://www.lintcode.com/en/problem/word-break/Given a string s and a dictionary of words dict, determine if s can be break into a space-separated sequence of one or more dictionary words.
Example
Given s = "lintcode", dict = ["lint", "code"].Return true because "lintcode" can be break as "lint code".
Answer
Run Time : 582ms
class Solution {
public:
/*
* @param s: A string
* @param dict: A dictionary of words dict
* @return: A boolean
*/
bool wordBreak(string &s, unordered_set<string> &dict) {
// write your code here
if (dict.size() <= 0) {
if (s.length() <= 0)
return true;
return false;
}
Trie trie;
for (auto d : dict)
trie.insert(d);
return wordBreakHelp(s, trie, 0);
}
private:
struct TrieNode {
TrieNode() {
for (int i = 0; i < 26; i++) {
next[i] = 0;
}
s = 0;
}
int s;
TrieNode* next[26];
};
class Trie {
public:
Trie() {
root = new TrieNode();
}
inline void deleteHelper(TrieNode* root) {
if (root) {
for (int i = 0; i < 26; i++) {
deleteHelper(root->next[i]);
}
delete root;
}
}
~Trie() {
deleteHelper(root);
root = 0;
}
void insert(string& s) {
TrieNode* iter = root;
for (auto c : s) {
if (iter->next[c - 'a'] == 0)
iter->next[c - 'a'] = new TrieNode();
iter = iter->next[c - 'a'];
}
iter->s = s.length();
}
unordered_set<int> search(string& s, int pos) {
TrieNode* iter = root;
unordered_set<int> words;
for (int i = pos; i < s.length(); i++) {
char c = s[i];
if (iter->next[c - 'a'] == 0)
break;
if (iter->s > 0) {
words.insert(iter->s);
}
iter = iter->next[c - 'a'];
}
if (iter->s > 0) {
words.insert(iter->s);
}
return words;
}
private:
TrieNode* root;
};
inline bool wordBreakHelp(string& s, Trie& trie, int pos) {
unordered_set<int> words = trie.search(s, pos);
if (s.length() > 0 && words.size() > 0) {
for (auto word : words) {
if ((pos + word) == s.length())
return true;
if (wordBreakHelp(s, trie, pos+word))
return true;
}
}
return false;
}
};
No comments:
Post a Comment