這種題一看,立馬就會想到遞迴,但直接遞迴的代價太大了,當字典裡的單詞長度很小,而單詞長度很長時,肯定會逾時的。再仔細想一下,是不是每次遞迴驗證都是有必要的呢?如果從i位置開始已經被驗證為不行了,那麼其他遞迴分支走到這個位置的時候就不用走了,因為肯定是死胡同。想到了打表,把不行的位置記錄下來,速度顯著提高。
下面說一點實現的事情,記錄一個位置行不行,用map最簡單直接,尋找速度也快。每次選擇步長的時候,不用從0到length,我的做法是先統計一下最長和最小的單詞長度,每次驗證這個長度就可以了。
代碼很簡單,一般不會出錯:
int mmin = 0x7fffffff, mmax = 0;map<int, bool> visited;bool pwordBreak(string &s, int start, unordered_set<string> &dict){ if(start >= s.length()) return true; if(visited.find(start) != visited.end()) return visited[start]; for(int i=mmin;i<=mmax&&start+i<=s.length();i++){ string sb = s.substr(start, i); if(dict.find(sb) != dict.end()){ if(pwordBreak(s, start+i, dict)){ visited[start+i] = true; return true; }else{ visited[start+i] = false; } } } return false;}class Solution {public: bool wordBreak(string s, unordered_set<string> &dict) { unordered_set<string>::const_iterator it = dict.begin(); while(it != dict.end()){ mmin = min(mmin, (int)(*it).length()); mmax = max(mmax, (int)(*it).length()); it++; } visited.clear(); return pwordBreak(s, 0, dict); }};