LeetCode127 Word Ladder
来源:6-5 BFS和图的最短路径 Perfect Squares
碳晚揽月
2019-06-13
bobo老师,这道题这两种BFS时间复杂度在我看来是一样的,但是最终运行的时间差距很大,具体原因是什么呢?
1.528ms
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
if( find( wordList.begin(), wordList.end(), endWord) == wordList.end())
return 0;
unordered_set<string> unSet( wordList.begin(), wordList.end());
queue< pair<string,int> > q; // < word in List, the depth till this word>
q.push( make_pair( beginWord, 1));
unSet.erase( beginWord);
vector<string> visited;
while( !q.empty() && !unSet.empty()) {
string s = q.front().first;
int depth = q.front().second;
q.pop();
visited.clear();
auto iter = unSet.begin();
for( ; iter != unSet.end(); ++iter) {
if( stringDefference( s, *iter) == 1) {
if( *iter == endWord)
return depth + 1;
q.push( make_pair( *iter, depth + 1));
visited.push_back( *iter);
// unSet.erase( iter); // wrong to erase directly
}
}
for( auto it = visited.begin();
it != visited.end(); ++it)
unSet.erase( *it);
}
return 0;
}
private:
int stringDefference( const string& s1, const string& s2) {
assert( s1.size() == s2.size());
assert( s1 != s2);
int res = 0;
for( int i=0; i<s1.size(); ++i) {
if( s1[i] != s2[i])
res ++;
}
return res;
}
};
- 80ms
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
if( find( wordList.begin(), wordList.end(), endWord) == wordList.end())
return 0;
unordered_set<string> dict( wordList.begin(), wordList.end());
queue< pair< string, int> > que;
que.push(make_pair(beginWord, 1));
dict.erase(beginWord);
while( !que.empty() && dict.size()>0) {
string str = que.front().first;
int ladder = que.front().second;
que.pop();
for( int i=0; i<str.size(); ++i) {
string tmpstr = str;
for(int j=0; j<26; ++j) {
tmpstr[i] = 'a'+j;
if(dict.find(tmpstr) != dict.end()) {
if( tmpstr == endWord) return ladder+1;
que.push( make_pair(tmpstr, ladder+1));
dict.erase(tmpstr);
}
}
}
}
return 0;
}
};
写回答
1回答
-
抱歉,你能不能用文字简单讲一讲两个代码的不同?我不可能做到同学们给我扔一片代码我就开始分析,请谅解:)
==========
两者时间复杂度不同。
第一种写法,每次寻找相邻的单词,要遍历一遍所有未访问的单词,每次遍历复杂度是O(n)的,n是单词个数。虽然随着循环的进行,n会逐渐减小;
第二中写法,每次寻找单词,是尝试把单词的每一个位置换一个字母,看是否存在,每次遍历复杂度是O(26 * 单词长度)。
如果有很多单词,每个单词都很短,第二种方式就会快很多。
当然,如果单词量比较少,但每个单词都很长,第一种方式快。
但看起来,测试用例,第一种情况更常见。这也是符合实际情况的。实际上,对于一个正常文本来说,英文单词的平均长度是4-5左右,乘以26才100这个数量级,对于单词数上千的情况,就已经能轻松体现出第二种方法的优势了:)
继续加油!:)
142019-06-14
相似问题