127号问题超时了...
来源:6-5 BFS和图的最短路径 Perfect Squares
紫云轩少主
2017-11-21
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
queue< pair<string,int> > q;
q.push(make_pair(beginWord,1));
unordered_set<string> visited;
visited.insert(beginWord);
while (!q.empty()){
string word = q.front().first;
int step = q.front().second;
q.pop();
for (int i = 0; i < wordList.size(); ++i) {
string a = wordList[i];
if (visited.find(a) != visited.end())
continue;
if (similarOne(word,a)){
if (a == endWord)
return step+1;
q.push(make_pair(a,step+1));
visited.insert(a);
}
}
}
return 0;
}
private:
bool similarOne(string& a,string& b){
int count = 0;
for (int i = 0; i < a.size(); ++i) {
if (a[i] != b[i])
count++;
if(count==2)
return false;
}
return true;
}
};老师,我的这个算法是超时的,您看看我这算法思路还有救么,我该怎么优化呢?
1回答
-
非常有救。是非常清晰的bfs呢:)不过这个问题数据稍微有点儿严格。
1)你的代码在bfs的过程中,每次while循环里的for循环,无论是visited.find(a);还是similarOne(word,a);或者if (a == endWord);或者visited.insert(a); 都需要O(len(a))这个级别的时间复杂度,可以使用初始化的方式,将整个图的节点表示成索引的形式而非字符串的形式,上述判断都可以做到O(1)的时间复杂度。使用这个思路,可以参考我的代码:https://github.com/liuyubobobo/Play-Leetcode/blob/master/0127-Word-Ladder/cpp-0127/main.cpp
2)visited使用unordered_set是很好的思路,更进一步,其实我们可以使用set存储我们待搜索的字符串,每次bfs一层以后将待搜索的字符串相应缩减。这样每次for循环并不需要遍历原始wordList中的所有字符串。这个思路可以参考我的代码:https://github.com/liuyubobobo/Play-Leetcode/blob/master/0127-Word-Ladder/cpp-0127/main2.cpp
3)这个问题数据这么严格,可能其实是想考察双向搜索。有兴趣可以在网上搜索自学一下双向搜索。这个课程没有讲双向搜索。事实上搜索策略种类繁多,完全可以单独做一门课程讲解了。anyway,我的参考代码:https://github.com/liuyubobobo/Play-Leetcode/blob/master/0127-Word-Ladder/cpp-0127/main4.cpp
022017-11-22
相似问题