先搞一个哈希表,键值是每个字典字符串的长度,对应的值是存储所有该长度字符串。之后对所有小于字符串长度的键值对应的数组进行遍历,若是字符串前“键值”个字符能够匹配,那就递归,一旦出现最后字符也匹配了,那就返回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 };