zoukankan      html  css  js  c++  java
  • leetcode-WordLadder

    Word Ladder

     Total Accepted: 10243 Total Submissions: 58160My Submissions

    Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:

    1. Only one letter can be changed at a time
    2. Each intermediate word must exist in the dictionary

    For example,

    Given:
    start = "hit"
    end = "cog"
    dict = ["hot","dot","dog","lot","log"]

    As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    return its length 5.

    Note:

    • Return 0 if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.

    Have you been asked this question in an interview?

     


       此题是图的遍历问题,要找一条起始点到目标点最短的路径。假设存在这种路径则返回路径长度,否则返回0。 刚開始想到用深度优先搜索遍历。可是时间复杂度太大,于是转为用宽搜,把起始点放入队列中,队列中的节点是一个字符串,由于要找到最短路径,所以在取出队首节点时要知道该节点属于第几层被搜索的节点,即路径长度,我用了levels来保存当前遍历的是第几层的节点,然后扩展该节点,把编辑距离为1而且在字典中出现的字符串增加队尾,并从字典中删除该字符串。


    在找编辑距离为1的字符串时,我试了两种方法,一种是遍历字典。找到编辑记录为1的字符串,假设字典数目非常大的话。每次都遍历字典耗时太多了,结果就是TLE,后来直接对节点字符串进行改动一个字符来得到扩展字符串才通过。

    <span style="font-size:14px;">class Solution {
    public:
        typedef queue<string,deque<string>> qq;
        int ladderLength(string start, string end, unordered_set<string> &dict) {
            //Use queue to implement bfs operation
            qq q;
            q.push(start);
            dict.erase(start);
            
            int currLevelLens = 1, nextLevelLens; 
            int levels = 1;  //To be returned answer, the total bfs levels be traversed
            string front, str;
            
            while (!q.empty()) {
                nextLevelLens = 0;
                while (currLevelLens--) {  // Traverse the node of current level
                    string front = q.front();
                    q.pop();
                    if (front == end)
                        return levels;
                    for (int i=0; i<front.size(); ++i) {
                        for (char j='a'; j<='z'; ++j) { // transform
                            if (front[i]=='j')
                                continue;
                            str = front;
                            str[i] = j;    
                            if (dict.find(str) != dict.end()) { 
                                ++nextLevelLens;
                                q.push(str);
                                dict.erase(str);
                            }
                        }
                    }
                }
                currLevelLens = nextLevelLens;
                ++levels;
            }
            return 0;
        }
        
    };
    </span>


    可是这个方案改变了dict的内容,有没有不改变dict的方法呢?我试了用一个unorder_set来保存被搜索过的字符串,可是耗时比前一种方法多。

    class Solution {
    public:
        typedef queue<string,deque<string>> qq;
        int ladderLength(string start, string end, unordered_set<string> &dict) {
            //Use queue to implement bfs operation
            qq q;
            q.push(start);
            
            int currLevelLens = 1, nextLevelLens; 
            int levels = 1;  //To be returned answer, the total bfs levels be traversed
            string front, str;
            searchedStrs.insert(start);
            while (!q.empty()) {
                nextLevelLens = 0;
                while (currLevelLens--) {  // Traverse the node of current level
                    string front = q.front();
                    q.pop();
                    if (front == end)
                        return levels;
                    for (int i=0; i<front.size(); ++i) {
                        for (char j='a'; j<='z'; ++j) { // transform
                            if (front[i]==j)
                                continue;
                            str = front;
                            str[i] = j;
                            
                            if (searchedStrs.find(str) == searchedStrs.end() && dict.find(str) != dict.end()) { 
                                ++nextLevelLens;
                                q.push(str);
                                //dict.erase(str);
                                searchedStrs.insert(str);
                            }
                        }
                    }
                }
                currLevelLens = nextLevelLens;
                ++levels;
            }
            return 0;
        }
    private:
        unordered_set<string> searchedStrs;
    };
    


    Python解法:

    有參考Google Norvig的拼写纠正样例:http://norvig.com/spell-correct.html

    class Solution:
        # @param word, a string
        # @return a list of transformed words
        def edit(self, word):
            alphabet = string.ascii_lowercase
            splits = [(word[:i],word[i:]) for i in range(len(word)+1)]
            replaces = [a+c+b[1:] for a,b in splits for c in alphabet if b]
            replaces.remove(word)
            return replaces
            
        # @param start, a string
        # @param end, a string
        # @param dict, a set of string
        # @return an integer
        def ladderLength(self, start, end, dict):
            currQueue = []
            currQueue.append(start)
            dict.remove(start)
            ret = 0
            while 1:
                ret += 1
                nextQueue = []
                while len(currQueue):
                    s = currQueue.pop(0)
                    if s == end:
                        return ret
                    editWords = self.edit(s)
    
                    for word in editWords:
                        if word in dict:
                            dict.remove(word)
                            nextQueue.append(word)
                if len(nextQueue)==0:
                    return 0
                currQueue = nextQueue
            return 0
     


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    注册博客园
    算法与数据结构-树-简单-二叉搜索树中的众数
    算法与数据结构-最小化舍入误差以满足目标
    算法与数据结构-设计有限阻塞队列
    分布式学习笔记2
    JS学习笔记1
    生活-上海租房经验
    分布式技术-学习笔记1
    HashMap-线程不安全的原因
    MySQL-复制
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4734022.html
Copyright © 2011-2022 走看看