LeetCode 126. 单词接龙 II

地址 https://leetcode-cn.com/problems/word-ladder-ii/

题目描述

按字典 wordList 完成从单词 beginWord 到单词 endWord 转化,
一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk 这样的单词序列,并满足:

每对相邻的单词之间仅有单个字母不同。
转换过程中的每个单词 si(1 <= i <= k)必须是字典 wordList 中的单词。
注意,beginWord 不必是字典 wordList 中的单词。
sk == endWord
给你两个单词 beginWord 和 endWord ,以及一个字典 wordList 。
请你找出并返回所有从 beginWord 到 endWord 的 最短转换序列 ,如果不存在这样的转换序列,返回一个空列表。
每个序列都应该以单词列表 [beginWord, s1, s2, ..., sk] 的形式返回。

 

示例 1:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
解释:存在 2 种最短的转换序列:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"

示例 2:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:[]
解释:endWord "cog" 不在字典 wordList 中,所以不存在符合要求的转换序列。
 

提示:
1 <= beginWord.length <= 7
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord、endWord 和 wordList[i] 由小写英文字母组成
beginWord != endWord
wordList 中的所有单词 互不相同

算法1

可以考虑每个单词 作为一个节点,每两个相差不超过一个字符的单词划上连线
那么就制作出一个图,我们求出最短路径即可

这里考虑另一种做法 使用哈希加BFS

BFS的广度遍历性质使得它处理最短路径有天然优势
在使用哈希记录每个单词到起点的最短距离避免重复选择,遍历完成后就得到答案。

C++ 代码

class Solution {
public:
	unordered_set<string > ss;
	vector<vector<string>> ans;
	unordered_map < string, int > mDis;

	bool Check(const string& a, const string& b) {
		if (a == b) return false;
		if (a.length() != b.length()) return false;
        int diff=0;
        for(int i = 0; i < a.size();i++){
            if(a[i] != b[i]) diff++;
            if(diff>1) return false;
        }
		return true;
	}

	vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
		for(auto&e:wordList) ss.insert(e);
		//包含结尾单词 直接结束
		if (ss.count(endWord) == 0) return  ans;

		queue<vector<string>> q;
		vector<string> tmp{ beginWord };
		mDis[beginWord] = 1;
		q.push(tmp);
		while (!q.empty()) {
			vector<string> curr = q.front(); q.pop();
			if (curr.back() == endWord) {
				ans.push_back(curr);
				continue;
			}
			for (auto it = ss.begin(); it != ss.end();it++) {
				if ( (mDis.count(*it) == 0 || mDis[*it] > curr.size()) && Check(*it, curr.back()) == true) {
					curr.push_back(*it);
					q.push(curr);
					mDis[*it] = curr.size();
					curr.pop_back();
				}
			}
		}

		return ans;
	}
};

127题目类似 不过题目时间要求更高
根据题目提供的数据
单词长度只有10 ,那么将单词每个字符尝试换成其他25个字母,然后查看该单词是否在字典中
时间效率更高

class Solution {
public:
	unordered_set<string> ss;
	unordered_map<string, int> dis;
	bool Check(const string& a, const string& b) {
		if (a == b) return false;
		if (a.length() != b.length()) return false;
		int diff = 0;
		for (int i = 0; i < a.size(); i++) {
			if (a[i] != b[i]) diff++;
			if (diff > 1) return false;
		}
		return true;
	}

	int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
		for (auto& e : wordList) ss.insert(e);
		if (ss.count(endWord) == 0) return 0;

		queue<pair<string, int>> q;
		q.push({ beginWord ,1 });
		while (!q.empty()) {
			pair<string, int> p = q.front(); q.pop();
			int step = p.second;
			string s = p.first;
			if (s == endWord) return step;
			for(int i =0;i <s.size();i++){
                for(int j = 0; j < 26;j++){
                    char c = j+'a';
                    char oldchar = s[i];
                    s[i]=c;
                    if(ss.count(s)!=0 && (dis.count(s) == 0||dis[s] > (step+1))){
                        dis[s] = step+1;
                        q.push({s,step+1});
                    }
                    s[i]=oldchar;
                }
            }
		}

		return 0;
	}
};

我的视频题解空间

posted on 2021-06-20 17:49  itdef  阅读(80)  评论(0编辑  收藏  举报

导航