1 解题思想
好久没更新了,作为顺序更新的强迫症系列,被卡死在这题上好久。
据说这道题是Leetcode上提交通过率最低的一题?我觉得其难度高,而且不给调试(作为白板写代码的表示很蛋疼)
言归正传,这道题和127的内容很近似,所以需要先看下这个127的报告。
Leetcode 127. Word Ladder 字符变换 解题报告
这道题的意思是,给了一个起始的单词,一个结束的单词,和一串词表
现在求从起始单词开始,每次选择词表中和起始单词仅有1个不同的单词,然后这个词再进行相同的操作,直到可以只改变一位得到结束的单词。
那么现在就存在一个变换的最短长度(到这里都是127里的简单版,即127只要求输出这个长度),怎么将BeginWord按照如上规则变换成EndWord。
而对于这道加强版来说,还需要输出所有符合最短长度的变换的路径,这道题的时间要求非常BT。。所以基本的解题思想是“
1、首先和127的方式一样,使用BFS遍历,不过这次的主要目的是记录出每个单词的最短变换长度(高度),即从start开始变换多少步可以到达
2、使用dfs的方式,从endword开始,根据1得到的高度按照深度优先的方式进行路径查找,当找到startword后加入一条路径(注意dfs方法里的beginword endword和原题的相反,答案也要做翻转)
代码写的很粗糙,也参照了别人的解法,就酱紫~~~
2 原题
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.
3 AC解
public class Solution {
HashMap<String,Integer> heights = new HashMap<String,Integer>();
//生成每个Word的高度
private void bfs(String beginWord,String endWord,Set<String> wordList){
Queue<String> queue = new LinkedList<String>();
queue.add(beginWord);
heights.put(beginWord,0);
String tmp = null;
while(queue.isEmpty() == false){
tmp = queue.poll();
if(tmp.equals(endWord)) continue;
char[] tmpChars = tmp.toCharArray();
char mychar = ' ';
//根据每个单词,按照26个字母进行构建
for(int i=0;i<tmp.length();i++){
for(char c='a';c<='z';c++){
if(c == tmpChars[i]) continue;
mychar = tmpChars[i];
tmpChars[i] = c;
String current = new String(tmpChars);
if((current.equals(endWord) || wordList.contains(current)) && heights.containsKey(current) == false){
int height = heights.get(tmp) + 1;
//System.out.println(current + " "+ height);
heights.put(current,height);
queue.add(current);
}
tmpChars[i] = mychar;
}
}
}
}
//使用DFS遍历结果
public void dfs(String beginWord,String endWord,Set<String> wordList, List <String> path,List<List<String>> res){
if(beginWord.equals(endWord) == true){
path.add(beginWord);
Collections.reverse(path);
res.add(path);
return;
}
if(heights.get(beginWord)==null) return ;
path.add(beginWord);
int nextHeight = heights.get(beginWord) - 1;
char[] tmpChars = beginWord.toCharArray();
char mychar = ' ';
for(int i=0;i<beginWord.length();i++){
for(char c='a';c<='z';c++){
if(c == tmpChars[i]) continue;
mychar = tmpChars[i];
tmpChars[i] = c;
String current = new String(tmpChars);
if(heights.containsKey(current) && heights.get(current) == nextHeight){
List<String> newPath = new ArrayList<String>(path);
dfs(current,endWord,wordList,newPath,res);
}
tmpChars[i] = mychar;
}
}
}
public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
//答案
System.out.println(beginWord+" "+endWord+" "+wordList.size());
List<List<String>> res = new ArrayList<List<String>>();
List<String> path = new ArrayList<String>();
bfs(beginWord,endWord,wordList);
// 注意不同
dfs(endWord,beginWord,wordList,path,res);
//System.out.println("@@@@@@@@@@@@@@");
return res;
}
}