Word Ladder II

leetcode: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) 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"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
解题思路:
1、使用图的广度优先搜索策略(BFS);
2、由于要返回所有的最短转换序列,使用unordered_map<string , vector<string>>来存储每个节点的前驱节点;
3、使用递归的形式,将unordered_map<string , vector<string>>中存放的节点顺序信息恢复成转换序列。
代码:
class Solution {
private:
        vector
    
    
     
     
      
      > pathes;
        void buildPathes(unordered_map
      
      
       
       > &traces , vector
       
       
        
         &path , const string end)
        {
            if(traces[end].size() == 0)
            {
                path.push_back(end);
                vector
        
        
          curPath = path; reverse(curPath.begin() , curPath.end()); pathes.push_back(curPath); path.pop_back(); return; } vector 
         
           prevs = traces[end]; path.push_back(end); for(vector 
          
            ::iterator it = prevs.begin() ; it != prevs.end() ; it++) { buildPathes(traces , path , *it); } path.pop_back(); } public: vector 
            
            
              > findLadders(string start, string end, unordered_set 
             
               &dict) { pathes.clear(); dict.insert(start); dict.insert(end); vector 
              
                prev; unordered_map 
               
                 > traces; for(unordered_set 
                
                  ::iterator it = dict.begin() ; it != dict.end() ; it++) { traces[*it] = prev; } vector 
                  
                  
                    > layer(2); bool cur = true; bool pre = false; layer[cur].insert(start); while(true) { cur = !cur; pre = !pre; for(unordered_set 
                   
                     ::iterator it = layer[pre].begin(); it != layer[pre].end() ; it++) { dict.erase(*it); } layer[cur].clear(); for(unordered_set 
                    
                      ::iterator it = layer[pre].begin(); it != layer[pre].end() ; it++) { for(int i = 0 ; i < (*it).size() ; i++) { string word = *it; int stop = word[i] - 'a'; for(int c = (stop + 1)%26 ; c != stop ; c = (c + 1)%26) { word[i] = c + 'a'; if(dict.find(word) != dict.end()) { traces[word].push_back(*it); layer[cur].insert(word); } } } } if(layer[cur].size() == 0) return pathes; if(layer[cur].count(end)) break; } vector 
                     
                       path; buildPathes(traces, path, end); return pathes; } }; 
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
        
       
       
      
      
     
     
    
    
疑点:根据unordered_map<string , vector<string>>中的节点信息,从end节点开始,递归往前推导,得出来的转换序列是全部转换序列,还是所有最短转换序列?答案肯定是返回所有的最短转换序列,首先可以这样想,在广度优先搜索的时候,Layer[pre]和Layer[cur]像剥洋葱一样,一层一层的向前推进,直到搜索到单词end的时候结束,那么从end再一层一层返回,得到的也会是最短的转换序列。换一种思路,假设在原单词表中,单词a可以直接到单词x,即a -> x,也可以经过单词b到单词x,即a -> b -> c ->x。当{a}为当前所搜索的层次时,记录x的前驱是a,b的前驱是a,所以,接下来搜索的一层是{b , x},然后在单词表中删除b、x,由此可以得出,b -> c -> x这个路径是记录不下来的。所以,广度优先搜索记录下来的路径是最短路径。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值