lintcode-单词接龙-120

给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列

比如:

  1. 每次只能改变一个字母。
  2. 变换过程中的中间单词必须在字典中出现。

您在真实的面试中是否遇到过这个题?
样例

给出数据如下:

start ="hit"

end = "cog"

dict = ["hot","dot","dog","lot","log"]

一个最短的变换序列是"hit" ->"hot"-> "dot" -> "dog" ->"cog"

返回它的长度 5

说明:在网上找到最多的就是这个方法,应该也是最好的方法了吧。求最短路径的BFS广度遍历算法。

class Solution {
public:
  
    int ladderLength(string start, string end, unordered_set<string> &dict) {  
        
        if(start.size() != end.size()) 
            return 0;  
        if(start.empty() || end.empty()||dict.empty())
            return 0;  
          
        queue<string>  path;//广度遍历都需要借助队列,存放着当前出队节点的所有子节点。
        path.push(start);  //第一个单词入队--开始节点
        
        map<string,int> count;//存放从开始节点到该节点的距离
        count[start]=1;      //开始节点存放着1
        
        dict.erase(start);    //避免走回头路 所以需要保证dict中无重复节点 
        
        while(dict.size()>0 && !path.empty()){  
            string curword = path.front(); //头结点出队!
            path.pop();  
            int  n=count[curword];    
            for(int i = 0; i < curword.size(); i++){ //嵌套的两个for循环作用是搜索出队节点的子节点  
                string tmp = curword;                //这里子节点的定义是指与该节点(该字符串)仅有一个字符不同的
                for(char j='a'; j<='z'; j++){        //的节点(该字符串)
                    if(tmp[i]==j)                 
                        continue;  
                    else
                        tmp[i]=j; //把curword的第i-1个字符改变成另一个字符(从‘a’到‘z’逐个试探)
                    
                    if(dict.find(tmp) != dict.end()){//如果改变后的字符串tmp在dict里面,说明curword和tmp相连
                        path.push(tmp); //入队
                        count[tmp]=n+1; //计入距离                                         
                        dict.erase(tmp);  //用完了就可以删除了 因为BFS每个节点只经过一次
                    }
                    if(tmp==end)
                        return count[tmp];  //tmp正好等end的话直接返回,因为BFS是层次遍历,越到后面层次会越深
                }                           //所以前面到达的必然是最小值!
            }  
        }  
        return 0;  
    } 
};


你可能感兴趣的:(lintcode-单词接龙-120)