您的位置:首页 > 其它

leetcode 126. Word Ladder II

2018-03-04 18:24 441 查看
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord toendWord, such that:Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,Given:
beginWord = 
"hit"

endWord = 
"cog"

wordList = 
["hot","dot","dog","lot","log","cog"]

Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Note:
Return an empty list if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word list.

You may assume beginWord and endWord are non-empty and are not the same.

这道题是LeetCode最难的之一了,刚开始直接做这个没做Word Ladder,感觉还是过于复杂搞不定。于是先回去做127 Word Ladder,用广度优先搜索得到最短的转换次数(详见127word Ladder)。
在此基础上,很容易将返回层数改造成返回每一层搜索到的字符串List,得到每一层的List之后还是可以先做剪枝,因为得到的是从前往后的每个相邻层之间的转换,可以利用从后往前搜索,排除不能到达的字符串。
例如题目中的例子每层就得到:
hit
hot
dot,lot
dog,log
cog
最后逐层构造转换List即可。看到其他博客说最后构造用的dfs,这里我用的bfs,感觉更直观

AC代码,372 ms,还有可以优化的地方:class Solution {
public List<List<String>> findLadders(String beginWord, String endWord,
List<String> wordList) {

if(!wordList.contains(endWord)){
return new ArrayList<List<String>>();
}
if(beginWord.equals(endWord)){
List<List<String>> list = new ArrayList<List<String>>();
List<String> strs = new ArrayList<String>();
strs.add(beginWord);
list.add(strs);
return list;
}
if(compareTwoStr(beginWord,endWord)){
List<List<String>> list = new ArrayList<List<String>>();
List<String> strs = new ArrayList<String>();
strs.add(beginWord);
strs.add(endWord);
list.add(strs);
return list;
}
if(wordList.contains(beginWord)){
wordList.remove(beginWord);
}
List<List<String>> list = new ArrayList<List<String>>();
list = ladders(beginWord,endWord,wordList);
if(list.size() == 0){
return list;
}

list = removeLadders(beginWord, endWord, wordList, list);
if(list.size() == 0){
return list;
}

List<List<String>> tempList = new ArrayList<List<String>>();
tempList.add(new ArrayList<String>());
tempList.get(0).add(beginWord);
List<List<String>> tempList2 = new ArrayList<List<String>>();
for(int i=1;i<list.size();i++){
for(String str: list.get(i)){
for(int j=0;j< tempList.size();j++){
if(compareTwoStr(str, tempList.get(j).get(tempList.get(j).size()-1))){
tempList2.add(new ArrayList<String>(tempList.get(j)));
tempList2.get(tempList2.size()-1).add(str);
}
}
}
tempList.clear();
tempList = new ArrayList<List<String>>(tempList2);
tempList2.clear();
}

return tempList;
}

public List<List<String>> ladders(String beginWord, String endWord, List<String> wordList) {
List<List<String>> list = new ArrayList<List<String>>();
list.add(new ArrayList<String>());
list.get(0).add(beginWord);
List<String> visited = new ArrayList<String>();
List<String> remain = new ArrayList<String>(wordList);
visited.add(beginWord);
int index = 0;
int visitLen = 1;
int count = 1;
while(!visited.contains(endWord)){
boolean found = false;
list.add(new ArrayList<String>());
for(int i=index;i<index+visitLen;i++){
for(int j=remain.size()-1 ;j>=0; j--){
if(compareTwoStr(remain.get(j), visited.get(i))
&& !visited.contains(remain.get(j))){
visited.add(remain.get(j));
list.get(list.size()-1).add(remain.get(j));
found = true;
remain.remove(j);
}
}

}
if(!found){
list.clear();
return list;
}
count++;
index += visitLen;
visitLen = visited.size() - index;
}

for(int i= list.get(list.size()-1).size()-1 ;i>=0;i--){
if(!list.get(list.size()-1).get(i).equals(endWord)){
list.get(list.size()-1).remove(i);
}
}
return list;

}

//辅助函数,判断两串只相差1字符
public boolean compareTwoStr(String str1,String str2){
int count = 0;
for(int i=0;i<str1.length();i++){
if(str1.charAt(i) != str2.charAt(i)){
count++;
if(count>1)
return false;
}
}
return count == 1;
}

//remove
public List<List<String>> removeLadders(String beginWord,
String endWord, List<String> wordList,List<List<String>> list) {
for(int i=list.size()-1;i>0;i--){
for(int j=list.get(i-1).size()-1;j>=0;j--){
boolean canReach = false;
for(String str2 : list.get(i)){
if(compareTwoStr(list.get(i-1).get(j), str2)){
canReach = true;
break;
}
}
if(!canReach){
list.get(i-1).remove(j);
}
}
}
return list;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: