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回答

liuyubobobo

2017-11-22

非常有救。是非常清晰的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

0
2
紫云轩少主
我使用了第二个优化建议,算法这个东西,实在是太精妙了,再次感谢!
2017-11-22
共2条回复

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

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

7408 学习 · 1150 问题

查看课程