最短單詞路徑
阿新 • • 發佈:2018-12-06
最短單詞路徑
給定兩個單詞(beginWord 和 endWord)和一個字典,找到從 beginWord到 endWord 的最短轉換序列的長度。轉換需遵循如下規則:
- 每次轉換隻能改變一個字母。
- 轉換過程中的中間單詞必須是字典中的單詞。
說明:
- 如果不存在這樣的轉換序列,返回 0。
- 所有單詞具有相同的長度。
- 所有單詞只由小寫字母組成。
- 字典中不存在重複的單詞。
- 你可以假設 beginWord 和 endWord 是非空的,且二者不相同。
class Solution { /* /* 把beginword新增到字典中;從字典中首先查詢將beginword改變一個字元的滿足條件的單詞;第一層節點; 其次,順著每一個節點再次查詢下去,首先遍歷到的滿足endword的節點路徑就是我們要找的最短路徑 這是一個廣度優先搜尋的問題 難點:如何構建滿足條件的查詢範圍--圖; 如何判斷一個字元是否經過一次改變就滿足條件; */ //1.總的函式 public int ladderLength(String beginWord, String endWord, List<String> wordList) { wordList.add(beginWord); int N=wordList.size(); int start=N-1; int end=0; //先在字典中找到endWord的座標 while(end<0 && !wordList.get(end).equals(endWord)){ end++; } //沒有找到 if(end==N){ return 0; } //構件圖--搜尋路徑 List<Integer>[] graphic = buildGraphic(wordList); return getShortestPath(graphic, start, end); } //2.構件圖---用索引來表示字元是否滿足條件 private List<Integer>[] buildGraphic(List<String> wordList){ int N=wordList.size(); List<Integer>[] graphic=new List[N]; for(int i=0;i<N;i++ ){ graphic[i]=new ArrayList<>(); for(int j=0;j<N;j++){ //如果滿足之改變一個字元就相等的條件 if(isConnect(wordList.get(i),wordList.get(j))){ graphic[i].add(j); } } } return graphic; } private boolean isConnect(String s,String t){ int diffcnt=0; int N=s.length(); for(int i=0;i<N && diffcnt<=1;i++){ if(s.charAt(i)!=t.charAt(i)){ diffcnt++; } } return diffcnt==1; } private int getShortestPath(List<Integer>[] graphic, int start, int end){ Queue<Integer> queue=new LinkedList<>(); int path=1; queue.add(start); boolean[] marked=new boolean[graphic.length]; marked[start]=true; while(!queue.isEmpty()){ int size=queue.size(); path++; while(size-- > 0){ int cur=queue.poll(); for(int next:graphic[cur]){ if(next==end){ return path; } if(marked[next]){ continue; } marked[next]=true; queue.add(next); } } } return 0; } }