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;
    }
};
  1. 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回答

liuyubobobo

2019-06-14

抱歉,你能不能用文字简单讲一讲两个代码的不同?我不可能做到同学们给我扔一片代码我就开始分析,请谅解:)


==========


两者时间复杂度不同。


第一种写法,每次寻找相邻的单词,要遍历一遍所有未访问的单词,每次遍历复杂度是O(n)的,n是单词个数。虽然随着循环的进行,n会逐渐减小;

第二中写法,每次寻找单词,是尝试把单词的每一个位置换一个字母,看是否存在,每次遍历复杂度是O(26 * 单词长度)。


如果有很多单词,每个单词都很短,第二种方式就会快很多。


当然,如果单词量比较少,但每个单词都很长,第一种方式快。


但看起来,测试用例,第一种情况更常见。这也是符合实际情况的。实际上,对于一个正常文本来说,英文单词的平均长度是4-5左右,乘以26才100这个数量级,对于单词数上千的情况,就已经能轻松体现出第二种方法的优势了:)


继续加油!:)


1
4
碳晚揽月
回复
liuyubobobo
谢谢bobo老师,我把第二种方法里find的时间复杂度想成O(n)了。。。以为两种都是O(n^2)
2019-06-14
共4条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程