Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: Only one letter can be changed at a time Each transformed word must exist in the word list. Note that beginWord is not a transformed word. For example, Given: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log","cog"] Return [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ] Note: Return an empty list if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. You may assume no duplicates in the word list. Yo
u may assume beginWord and endWord are non-empty and are not the same.面試
相比於Word Ladder I,II要求返回全部的最短路徑。算法
在繼續往下看以前,請先參考I的這篇博客
首先咱們再來查看一下題目中的例子。其實咱們能夠將路徑化爲有向圖,而後將有向圖中從beginWord至endWord的最短路徑所有枚舉出來。這裏須要考慮最合適的數據結構。graph的話咱們經過Map<String,List<String>>
來記錄節點和從該節點出發能夠到達的其它節點。在題中的含義也就是s1所能轉換的全部s2。至於如何生成該有向圖,則須要經過廣度優先算法,利用隊列
來實現。將每一層的string分別入棧。若是遇到endWord則至該層結尾廣度優先算法結束。segmentfault
這裏有一個能夠提升的計算效率的數據結構。在一開始,我經過一個list來記錄全部上層已經遍歷過的string。經過這種方式來防止造成圈。可是這樣的形式形成的代碼的超時,因此換成了Map<String, Integer>來記錄String的最低層數。微信
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { Map<String, Integer> ladder = new HashMap<String, Integer>(); for(int i = 0 ; i<wordList.size() ; i++){ ladder.put(wordList.get(i), Integer.MAX_VALUE); } ladder.put(beginWord, 0); Queue<String> q = new LinkedList<String>(); int minStep = Integer.MAX_VALUE; if(beginWord!=null){ q.offer(beginWord); while(!q.isEmpty()){ String current = q.poll(); int step = ladder.get(current)+1; if(step>minStep) break; for (int i = 0; i < current.length(); i++){ StringBuilder sb = new StringBuilder(current); for (char ch='a'; ch <= 'z'; ch++){ sb.setCharAt(i, ch); String sbs = sb.toString(); if(ladder.containsKey(sbs)){ if(step>ladder.get(sbs)) continue; else if(step<ladder.get(sbs)){ q.add(sbs); ladder.put(sbs, step); } if(map.containsKey(current)){ map.get(current).add(sbs); }else{ Set<String> list= new HashSet<String>(); list.add(sbs); map.put(current,list); } if(sbs.equals(endWord)) minStep = step; } } } } } generatePath(beginWord, endWord, new ArrayList<String>()); return result; } public void generatePath(String currentWord, String endWord, List<String> current){ current.add(currentWord); if(currentWord.equals(endWord)){ result.add(new ArrayList<String>(current)); }else{ Set<String> set = map.get(currentWord); if(set!=null){ for(String s : set){ generatePath(s, endWord,current); } } } current.remove(current.size()-1); }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~數據結構