題目:
從開始單詞到結束單詞,藉助字典是否可達,如果可達路徑長度是多少?
一個例子:
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中移動位置的;你需要把他取出來在放進去一次。