zoukankan      html  css  js  c++  java
  • Word Ladder

    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.

    这道题目首先想到的是DFS,或曰backtracking,也就是每次都找到一个可能的路径,最后比较所有路径中最小的就是题目所求。这样做显然需要较多的时间,因为我们遍历了所有的可能性。那么,有没有更加快捷的方案呢?
    答案是显然的,那就是BFS。CareerCup上有这道题目,当时没有注意总结成这么抽象的方法,这次一定要好好总结一下。首先,虽然题目中没有一个“图”的概念,但是我们可以假想构建一个图,其中图中的每个顶点都是我们的元素,点和点是如何联系起来的呢?如果一个单词通过改变一次字母,能够变成另外一个单词,我们称之为1 edit distance 距离(是不是想起了leetcode中edit distance那道题目了?)所以,图中的所有相邻元素都是edit distance 距离为1的元素。那么,我们只需要做BFS,哪里最先遇到我们的target word,那么我们的距离就是多少。如果遍历完所有的元素都没有找到target word,那么我们就返回1。
    另外一个需要注意的地方就是,如果我们曾经遍历过某个元素,我会将其从字典中删除,以防以后再次遍历到这个元素。这里有几种情况:
    1.以后再也遍历不到这个元素,那么我们删除它当然没有任何问题。
    2.我们以后会遍历到该元素,又分为两种情况:
    (1)在本层我们就能遍历到该元素。也就是说,我们到达这个元素有两条路径,而且它们都是最短路径。
    举一个例子应该比较容易理解:比如hot->hog->dog->dig和hot->dot->dog->dig,那么在第一次遍历距离hot为1的元素时,我们找到了hog和dot。对hog遍历时,我们找到了dog,并且将其从字典中删除。那么在遍历距离dot为1的元素时,我们实际上是找不到dog的,因为已经被删除了。对于本题来说,是没有什么影响的,因为到dog距离都是3,到dig距离都是4。但是后面我们做word ladder 2的时候,如果没有考虑这个情况,将是非常致命的,因为题目要求输出最短路径的所有情况,我们稍后讨论相关问题
    (2)在更下层我们才能够遍历到该元素。比如hot->dot->dog->dig和hot->hat->dat->dag->dog->dig,如果第一次我们找到了dog并且将其删除,那么第二次我们实际上是找不到这个元素的。这样对于本题来说,没有任何影响。对于word ladder 2来说,因为也是要输出最短路径,所以也不会有任何影响。但是倘若我们要输出从起点到终点的所有路径,那么我们就要小心这种情况了。参考:http://blog.csdn.net/zxzxy1988/article/details/8591890

    这道题看似一个关于字符串操作的题目,其实要解决这个问题得用图的方法。我们先给题目进行图的映射,顶点则是每个字符串,然后两个字符串如果相差一个字符则我们进行连边。接下来看看这个方法的优势,注意到我们的字符集只有小写字母,而且字符串长度固定,假设是L。那么可以注意到每一个字符可以对应的边则有25个(26个小写字母减去自己),那么一个字符串可能存在的边是25*L条。接下来就是检测这些边对应的字符串是否在字典里,就可以得到一个完整的图的结构了。根据题目的要求,等价于求这个图一个顶点到另一个顶点的最短路径,一般我们用广度优先搜索。这个算法中最坏情况是把所有长度为L的字符串都看一下,或者把字典中的字符串都看一下,而长度为L的字符串总共有26^L,所以时间复杂度是O(min(26^L, size(dict)),空间上需要存储访问情况,也是O(min(26^L, size(dict))。

    C++实现代码:

    #include<iostream>
    #include<string>
    #include<unordered_set>
    #include<queue>
    using namespace std;
    
    class Solution
    {
    public:
        int ladderLength(string start, string end, unordered_set<string> &dict)
        {
            if(start.empty()||end.empty()||dict.empty())
                return 0;
            int level=1;
            int count=0;
            int curr=0;
            int i;
            queue<string> q;
            q.push(start);
            count++;
            while(!q.empty())
            {
                string tmp=q.front();
                q.pop();
                count--;
                for(i=0; i<(int)tmp.size(); i++)
                {
                    char ctmp=tmp[i];
                    for(char c='a'; c<='z'; c++)
                    {
                        if(tmp[i]==c)
                            continue;
                        tmp[i]=c;
                        if(tmp==end)
                            return level+1;
                        if(dict.count(tmp)>0)
                        {
                            q.push(tmp);
                            curr++;
                            dict.erase(tmp);
                        }
                        tmp[i]=ctmp;
                    }
                }
                if(count==0)
                {
                    level++;
                    count=curr;
                    curr=0;
                }
            }
            return 0;
        }
    };
    
    int main()
    {
        Solution s;
        string start = "hot";
        string end = "dog";
        unordered_set<string> dict = {"hot","dog"};
        cout<<s.ladderLength(start,end,dict)<<endl;
    }
  • 相关阅读:
    静态方法、类方法和属性方法
    类的私有属性和私有方法
    JMeter-正则表达式(取出银行卡号后4位)
    JMeter连接MySQL数据库
    解决chrome提示您的连接不是私密连接的方法
    python安装appium模块
    mac中的word内容丢失
    有些事一旦开始就停不下来了
    Python接口测试-以&连接拼接字典数据(get中url请求数据)
    Python接口测试-模块引用与映射
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4132227.html
Copyright © 2011-2022 走看看