问题
例子
思路
wordList中可以没有beginWord,但是要有endWord
问题抽象为无向无权图,单词为结点,差一个字母的单词之间连边。问题变成找到从起点到终点的最短路径,如果存在的话。因此可以使用广度优先搜索方法。
递归深度遍历,超时
所以考虑采用广度遍历
-
方法1
-
方法2
代码
//方法1 我的dfs 超时
class Solution {
private int res = Integer.MAX_VALUE;
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
if(!wordList.contains(endWord)) return 0;
boolean[] used = new boolean[wordList.size()];
//因为还有beginWord没有算上
backtrack(wordList,endWord,used,beginWord,1);
return res==Integer.MAX_VALUE?0:res;
}
public void backtrack(List<String> wordList, String endWord, boolean[] used, String now, int len) {
if(now.equals(endWord)) {
res = Math.min(res,len);
return;
}
for(int i=0; i<wordList.size(); i++) {
if(used[i]==true) continue;
else if(check(wordList.get(i),now)){
used[i]=true;
backtrack(wordList,endWord,used,wordList.get(i),len+1);
used[i]=false;
}
}
}
public boolean check(String a, String b) {
int dist=0;
for(int i=0; i<a.length(); i++) {
if(a.charAt(i)!=b.charAt(i)) {
dist++;
if(dist>1) return false;
}
}
return dist==1;
}
}
//方法2
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
if(!wordList.contains(endWord)) return 0;
boolean[] used = new boolean[wordList.size()];
int level = 0;
Queue<String> q = new LinkedList<>();
int index = wordList.indexOf(beginWord);
if(index>-1) used[index]=true;
q.offer(beginWord);
while(q.size()>0) {
level++;
int len = q.size();
for(int i=0; i<len; i++) {
String now = q.poll();
for(int j=0; j<wordList.size(); j++) {
//先把错误的都去掉
if(used[j]==true) continue;
String next = wordList.get(j);
if(dist(now, next)==false) continue;
if(next.equals(endWord)) return level+1;
used[j]=true;
q.offer(next);
}
}
}
return 0;
}
//距离是否为1
public boolean dist(String a, String b) {
int dist=0;
for(int i=0; i<a.length(); i++) {
if(a.charAt(i)!=b.charAt(i)) {
dist++;
if(dist>1) return false;
}
}
return dist==1;
}
}