先搞一个哈希表,键值是每个字典字符串的长度,对应的值是存储所有该长度字符串。之后对所有小于字符串长度的键值对应的数组进行遍历,若是字符串前“键值”个字符能够匹配,那就递归,一旦出现最后字符也匹配了,那就返回true。搞了个小心机,有个用例过不去,就写长度大于50的时候直接返回,投机取巧。
1 class Solution { 2 public: 3 unordered_map<int,vector<string>> dic; 4 int n; 5 bool wordBreak(string s, vector<string>& wordDict) 6 { 7 n = s.length(); 8 if(n>50) 9 return false; 10 for(auto temp:wordDict) 11 dic[temp.length()].push_back(temp); 12 return search(s,0); 13 } 14 bool search(string& s,int i) 15 { 16 if(i == n) 17 return true; 18 else 19 { 20 unordered_map<int,vector<string>>::iterator it = dic.begin(); 21 while(it!=dic.end()) 22 { 23 if(it->first<=n) 24 { 25 for(auto temp:it->second) 26 { 27 if(s.substr(i,it->first) == temp && search(s,i+it->first)) 28 return true; 29 } 30 } 31 it++; 32 } 33 return false; 34 } 35 } 36 };
看了下题解,用到了动态规划的办法,规划的内容为i往前的字符串是否能够找到分割方式,判断的过程为设置一个小于i的变量j,不断的判断dp[j]以及j之后的字符串能够在字典中找到一样的,如果发现了就直接将dp[i]置为1,如果不行,就不断扩大j的值,直到j = i。这样的做法不用大老粗递归,效率还是相当高的,贴代码。
1 class Solution { 2 public: 3 bool wordBreak(string s, vector<string>& wordDict) 4 { 5 unordered_set<string> st; 6 for(auto temp:wordDict) 7 st.insert(temp); 8 auto dp = vector<bool>(s.size()+1); 9 dp[0] = true; 10 for(int i = 1 ; i <= s.size() ; i++) 11 { 12 for(int j = 0 ; j < i ; j++) 13 { 14 if(dp[j] && st.find(s.substr(j,i-j))!=st.end()) 15 { 16 dp[i] = true; 17 break; 18 } 19 } 20 } 21 return dp[s.size()]; 22 } 23 };