这种题一看,立马就会想到递归,但直接递归的代价太大了,当字典里的单词长度很小,而单词长度很长时,肯定会超时的。再仔细想一下,是不是每次递归验证都是有必要的呢?如果从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); } };
leetcode第一刷_Word Break
时间: 2024-10-06 11:11:18