Word Ladder 2

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.

分析:

给定一个单词start, 问通过一系列变换是否能够得到单词end, 中间的单词都必须是给定的字典中的词。

其实就是 从最初的一个状态,能够找到一个path, 到达最终的一个状态。

Bingo! 图的搜索: 找到图中两个node之间的所有的最短路径。

图的搜索有 深度优先(DFS) 和 广度优先(BFS)两种。

BFS适用于解决寻找最短路径的问题,因此采用BFS


class Solution {
public:
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
        //BFS   each node in graph has multipul fathers
        vector<vector<string> > result;
        vector<string> path;
        bool found = false;
        unordered_set<string> visited;
        unordered_map<string, vector<string> > father;
        unordered_set<string> current, next;
        
        if(start.size() != end.size()) return result;
        
        current.insert(start);
        while(!current.empty())
        {
		  for(auto i : current) 
		    visited.insert(i);

		  for(auto str : current)
		  {
            for(size_t i=0; i<str.size(); ++i)
            {
                string new_str(str);
                for(char c = 'a'; c <= 'z'; ++c)
                {
                    if(c == new_str[i]) continue;
                    
                    swap(c, new_str[i]);
                    if(new_str == end || dict.count(new_str) > 0 && !visited.count(new_str)){
                        //visited.insert(new_str);
                        next.insert(new_str);
                        father[new_str].push_back(str);
                    }
                    if(new_str == end){
                        found = true;
                        break;
                    }
                    swap(c, new_str[i]);
                }
            }
		  }// end for
		  current.clear();
          if(!found){
		    swap(current, next);
		  }
        }// end while
        
        buildPath(father, path, start, end, result);
        return result;
    }
private:
    void buildPath(unordered_map<string, vector<string> > &father, vector<string> &path, 
                    const string &start, const string &word, vector<vector<string> > &result){
        path.push_back(word);
        if(word == start){
            result.push_back(path);
            reverse(result.back().begin(), result.back().end());
        }
        else{
            for(auto f : father[word])
              buildPath(father, path, start, f, result);
        }
        path.pop_back();
    }
};


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值