LeetCode Word Break
class Solution { private: int* memo; public: bool wordBreak(string s, unordered_set<string> &dict) { memo = new int[s.length() + 1]; for (int i=0; i<=s.length(); i++) memo[i] = -1; bool ret = dfs(s, 0, dict); delete[] memo; return ret; } bool dfs(string& s, int pos, unordered_set<string> &dict) { if (pos >= s.length()) return true; int rest_len = s.length() - pos; for (int i = rest_len; i >=1; i--) { if (dict.find(s.substr(pos, i)) != dict.end()) { if (memo[pos + i] == -1) { memo[pos + i] = dfs(s, pos + i, dict); } if (memo[pos + i] == 1) return true; } } return false; } };
最开始直接用了暴力超时,因为有许多重复计算步骤,可以使用memorize把这些步骤的结果存储起来(更以前用递归算斐波拉契数列一样),常常用这种方式可以解决的问题也可以改写为DP形式,代码如下,快了不少,在5ms左右。
class Solution { public: bool wordBreak(string s, unordered_set<string> &dict) { bool* dp = new bool[s.length() + 1]; for (int i=0; i<=s.length(); i++) dp[i] = false; dp[0] = true; for (int i=1; i<=s.length(); i++) { for (int j=i-1; j>=0; j--) { if (dict.find(s.substr(j, i-j)) != dict.end() && dp[j]) { dp[i] = true; break; } } } bool ret = dp[s.length()]; delete[] dp; return ret; } };
第二轮:
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"
.
还是只会用memo不能直接写出dp,真挫啊!
第三轮:
凭着记忆写吧
1 class Solution { 2 public: 3 bool wordBreak(string s, unordered_set<string>& wordDict) { 4 int len = s.size(); 5 vector<bool> dp(len + 1, false); 6 dp[0] = true; 7 8 for (int i=1; i<=len; i++) { 9 for (int j=i-1; j>=0; j--) { 10 if (!dp[j]) continue; 11 string p = s.substr(j, i - j); 12 if (wordDict.count(p) > 0) { 13 dp[i] = true; 14 break; 15 } 16 } 17 } 18 return dp[len]; 19 } 20 };