Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- 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 length5.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
一开始的想法是dfs,时间复杂度很高,后来改成了bfs,通过。
具体解析:http://blog.youkuaiyun.com/zxzxy1988/article/details/8591890 ,在这道题中是允许剪枝的,之后出的变种好像就不允许这么做了
BFS:
static int ladderLength(String start, String end, Set<String> dict) {
Queue<String> Q = new LinkedList<>();
Q.offer(start);
int res = 1;
while (!Q.isEmpty()) {
int qsize = Q.size(); //层次遍历,记录当前队列大小
while (qsize != 0) {
char[] chars = Q.poll().toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i]; //对队列头字符串每一个字符进行替换
for (char c = 'a'; c <= 'z'; c++) { // 这里在每个字符位上必须要循环26次,相比较直接拿字典中的词进行比较,时间复杂度?
chars[i] = c;//替换字符
String word = new String(chars);
// Found the end word
if (word.equals(end))
return res + 1;//找到答案,退出
if (dict.contains(word)) {
Q.add(word);//变换在字典中找到了
dict.remove(word);//从字典中删除
}
}
chars[i] = ch;//还原队列头字符串,因为有可能在字典中可以找到多个“近邻字符串”
}
qsize--;
}
res++;//遍历一层,res+1
}
return 0;
}
之前做的DFS:
public class Solution {
int result = Integer.MAX_VALUE;
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
boolean[] flag = new boolean[wordList.size()];
helper(beginWord,endWord,wordList,flag,1);
if(result==Integer.MAX_VALUE)
return 0;
return result;
}
public boolean helper(String beginWord, String endWord, List<String> wordList, boolean[] flag, int now){
if(beginWord.equals(endWord)){
if(now<result){
result = now;
return true;
}
return false;
}
for(int i = 0; i<wordList.size(); i++){
if(flag[i]==false&&judge(beginWord,wordList.get(i))){
flag[i]=true; // 设置访问标志
if(!helper(wordList.get(i),endWord,wordList,flag,now+1)){ // 继续迭代,如果返回false,则将标志位重置,继续访问下一个
flag[i]=false;
}
else
break;
}
}
return false;
}
public boolean judge(String s1,String s2){
int count = 0;
char[] a = s1.toCharArray();
char[] b = s2.toCharArray();
for(int i = 0 ;i < a.length; i++){
if(a[i]!=b[i]){
++count;
if(count>1)
return false;
}
}
return true;
}
}