zoukankan      html  css  js  c++  java
  • 18. Word Ladder && Word Ladder II

    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.

    思想:宽度优先搜索(BFS)即可。(可从头往尾部搜,也可从尾往头部搜,)。

    我的方案中,使用两个 hash_set 分别存储当前层和下一层结点,另一个 hash_set存储之前遍历过的结点。

    class Solution {
    public:
    	int ladderLength(string start, string end, unordered_set<string> &dict) {
    		int ans = 0;
    		unordered_set<string> previousNodes;
    		vector<unordered_set<string> > node_levels(2);
    		int curLevel = 0; // which is index belong to vector node_levels.
    		node_levels[curLevel].insert(end);
    		ans++;
    		unordered_set<string>::iterator it;
    		while(!node_levels[curLevel].empty()) {
    			for(it = node_levels[curLevel].begin(); it != node_levels[curLevel].end(); ++it) {
    				for(size_t i = 0; i < it->size(); ++i) {
    					string node(*it);
    					for(node[i] = 'a'; node[i] <= 'z'; ++node[i]) {
    						if(node == start) return (ans+1); // output 1
    						if(previousNodes.count(node) || node_levels[curLevel].count(node) || node[i] == (*it)[i] || !dict.count(node))
    						    continue;
    						node_levels[!curLevel].insert(node);
    					}
    				}
    				previousNodes.insert(*it);
    			}
    			node_levels[curLevel].clear();
    			curLevel = !curLevel;
    			ans++;
    		}
    		return 0; // output 2
    	}
    };
    

    Word Ladder II

    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.

        思想: 在 I 的基础之上, 加入 hash_map 记下每条边, 从 end 开始搜索,建立以 start 为源点,end 为汇点的图,然后从 start 开始深搜即可。

    typedef pair<string, string> PAIR;
    void  getSolution(string &end, string& word, unordered_multimap<string, string> &map, vector<vector<string> > &vec, vector<string> &vec2) {
    	if(word == end) {
    		vec.push_back(vec2);
    		vec.back().push_back(word);
    		return;
    	}
    	pair<unordered_map<string, string>::iterator, unordered_map<string, string>::iterator> ret;
    	ret = map.equal_range(word);
    	while(ret.first != ret.second) {
    		vec2.push_back(ret.first->first);
    		getSolution(end, ret.first->second, map, vec, vec2);
    		vec2.pop_back();
    		ret.first++;
    	}
    }
    class Solution {
    public:
    	vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
    		vector<vector<string>> vec;
    		unordered_multimap<string, string> edges;
    		unordered_set<string> previousNodes; 
    		vector<unordered_set<string> > node_levels(2);
    		int curLevel = 0; // an index belong to vector node_levels
    		node_levels[curLevel].insert(end);
    		unordered_set<string>::iterator it;
    		while(!node_levels[curLevel].empty() && node_levels[curLevel].count(start) == 0) {
    			for(it = node_levels[curLevel].begin(); it != node_levels[curLevel].end(); ++it) {
    				for(size_t i = 0; i < it->size(); ++i) {
    					string node(*it);
    					for(node[i] = 'a'; node[i] <= 'z'; ++node[i]) {
    						if(node == start) { 
    							node_levels[1-curLevel].insert(node);
    							edges.insert(PAIR(start, *it));
    							break;
    						}
    						if(previousNodes.count(node) || node_levels[curLevel].count(node) || dict.count(node) == 0) 
    						    continue;
    						node_levels[1-curLevel].insert(node);
    						edges.insert(PAIR(node, *it));
    					}
    				}
    				previousNodes.insert(*it);
    			}
    			node_levels[curLevel].clear();
    			curLevel = !curLevel;
    		}
    		previousNodes.clear();
    		if(node_levels[curLevel].empty()) return vec;
    		vector<string> vec2;
    		getSolution(end, start, edges, vec, vec2);
    		return vec;
    	}
    };
    
  • 相关阅读:
    30天敏捷生活(4): 撰写个人使命宣言
    [智力考题]比尔盖茨只有3分的考题
    推荐下载:MSN机器人源代码(C#),含自动IP地址查询、简单自动问答等(添加详细使用)
    [代码]包括所有特性的目录选择对话框
    开源数据库系统之SQLite3.2.0、FireBird2.0 Alpha1等
    [建议]添加模板功能
    到底SQLite有多强?在我的2台机器上的压力测试
    OMEA Pro,刚刚荣获15届Jolt大奖,综合RSS阅读,邮件、任务等管理的IIM(智能信息管理)
    关于DotNetNuke(DNN)的语言问题
    写你自己的反编译/混淆器
  • 原文地址:https://www.cnblogs.com/liyangguang1988/p/3933973.html
Copyright © 2011-2022 走看看