题目:
从开始单词到结束单词,借助字典是否可达,如果可达路径长度是多少?
一个例子:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
思路:
1. 用一个集合来储存现在那些单词是可达的。BFS来寻找剩下的单词。
2. 再说一个非常傻的想法,主要是为了练习dijkstra算法的写法。就是用这写单词计算出所有的链接关系,存在一张图中,开始节点到结束节点的距离+1就是路径长度。
那个很傻的程序的写法:(会超时的!)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;
public class Solution {
public boolean isconnected(String a, String b) {
int cnt = 0;
for(int i = 0; i < a.length(); i++) {
if(a.charAt(i) != b.charAt(i))
cnt++;
}
if(cnt == 1) return true;
return false;
}
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
if(wordList.contains(beginWord))
wordList.remove(beginWord);
if(wordList.contains(endWord))
wordList.remove(endWord);
int graphsize = wordList.size()+2;
int[][] graph = new int[graphsize][graphsize];
List<Vertex> nodelist = new ArrayList<>();
nodelist.add(new Vertex(beginWord,0));
for(String wd: wordList) nodelist.add(new Vertex(wd,Integer.MAX_VALUE));
nodelist.add(new Vertex(endWord,Integer.MAX_VALUE));
PriorityQueue<Vertex> Q = new PriorityQueue<Vertex>(nodelist);
/*step1 construct graph*/
for(int i = 0; i < graphsize; i++) {
for(int j = i+1; j < graphsize; j++)
if(isconnected(nodelist.get(i).content, nodelist.get(j).content)) {
graph[i][j] = 1;
graph[j][i] = 1;
}
}
/*step2 dijkstra algorithm*/
while(!Q.isEmpty()) {
Vertex uVertex = Q.poll();
if(uVertex.dist != Integer.MAX_VALUE && uVertex.id == nodelist.size()-1) return uVertex.dist+1;
for(int i = 0; i < graphsize; i++) {
if(graph[uVertex.id][i] == 1) {
//relex two node
if(nodelist.get(i).dist > uVertex.dist+1) {
nodelist.get(i).dist = uVertex.dist+1;
nodelist.get(i).prev = uVertex;
Q.remove(nodelist.get(i));
Q.add(nodelist.get(i));
}
}
}
}
return 0;
}
public static void main(String[] args) {
Set<String> wdlist = new HashSet<String>(Arrays.asList("dot","dog"));
System.out.println(new Solution().ladderLength("hot", "dog", wdlist));
}
}
class Vertex implements Comparable<Vertex>{
static int cnt = 0;
int id;
String content;
Vertex prev = null;
int dist = Integer.MAX_VALUE;
public Vertex(String content, int dist) {
this.content = content;
this.dist = dist;
this.id = cnt;
cnt++;
}
@Override
public int compareTo(Vertex o) {
if(this.dist > o.dist) return 1;
else if(this.dist < o.dist) return -1;
else return 0;
}
}
注意:
1. 初始化priorityqueue是直接用一个list初始化的,这些相当于只是把指针一个个移过去;
2. 当queue中元素的键值发生变化,他是不会自动在queue中移动位置的;你需要把他取出来在放进去一次。