Leetcode: Word Ladder II

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:



Only one letter can be changed at a time

Each intermediate word must exist in the dictionary

For example,



Given:

start = "hit"

end = "cog"

dict = ["hot","dot","dog","lot","log"]

Return

  [

    ["hit","hot","dot","dog","cog"],

    ["hit","hot","lot","log","cog"]

  ]

Leetcode 里面通过概率最低的一道题,参看了别人的解法:利用bfs 层序遍历 如果队列中有end 那么结束遍历(到最短的一层就结束)

  1 import java.util.ArrayList;

  2 import java.util.HashMap;

  3 import java.util.HashSet;

  4 import java.util.LinkedList;

  5 import java.util.List;

  6 import java.util.Map;

  7 import java.util.Queue;

  8 import java.util.Set;

  9 

 10 public class Solution {

 11     class WordWithLevel {

 12         String word;

 13         int level;

 14 

 15         public WordWithLevel(String word, int level) {

 16             this.word = word;

 17             this.level = level;

 18         }

 19     }

 20 

 21     private String end;

 22     private ArrayList<ArrayList<String>> result;

 23     private Map<String, List<String>> nextMap;

 24 

 25     public ArrayList<ArrayList<String>> findLadders(String start, String end,

 26             HashSet<String> dict) {

 27         result = new ArrayList<ArrayList<String>>();

 28         this.end = end;

 29 

 30         // unvisited words set

 31         Set<String> unVisited = new HashSet<String>();

 32         unVisited.addAll(dict);

 33         unVisited.add(start);

 34         unVisited.remove(end);

 35 

 36         // used to record the map info of <word : the words of next level>

 37         nextMap = new HashMap<String, List<String>>();

 38         for (String e : unVisited) {

 39             nextMap.put(e, new ArrayList<String>());

 40         }

 41 

 42         // BFS to search from the end to start

 43         Queue<WordWithLevel> queue = new LinkedList<WordWithLevel>();

 44         queue.add(new WordWithLevel(end, 0));

 45         boolean found = false;

 46         int finalLevel = Integer.MAX_VALUE;

 47         int currentLevel = 0;

 48         int preLevel = 0;

 49         Set<String> visitedWordsInThisLevel = new HashSet<String>();

 50         while (!queue.isEmpty()) {

 51             WordWithLevel wordWithLevel = queue.poll();

 52             String word = wordWithLevel.word;

 53             currentLevel = wordWithLevel.level;

 54             if (found && currentLevel > finalLevel) {

 55                 break;

 56             }

 57             if (currentLevel > preLevel) {

 58                 unVisited.removeAll(visitedWordsInThisLevel);

 59             }

 60             preLevel = currentLevel;

 61             char[] wordCharArray = word.toCharArray();

 62             for (int i = 0; i < word.length(); ++i) {

 63                 char originalChar = wordCharArray[i];

 64                 boolean foundInThisCycle = false;

 65                 for (char c = 'a'; c <= 'z'; ++c) {

 66                     wordCharArray[i] = c;

 67                     String newWord = new String(wordCharArray);

 68                     if (c != originalChar && unVisited.contains(newWord)) {

 69                         nextMap.get(newWord).add(word);

 70                         if (newWord.equals(start)) {

 71                             found = true;

 72                             finalLevel = currentLevel;

 73                             foundInThisCycle = true;

 74                             break;

 75                         }

 76                         if (visitedWordsInThisLevel.add(newWord)) {

 77                             queue.add(new WordWithLevel(newWord,

 78                                     currentLevel + 1));

 79                         }

 80                     }

 81                 }

 82                 if (foundInThisCycle) {

 83                     break;

 84                 }

 85                 wordCharArray[i] = originalChar;

 86             }

 87         }

 88 

 89         if (found) {

 90             // dfs to get the paths

 91             ArrayList<String> list = new ArrayList<String>();

 92             list.add(start);

 93             getPaths(start, list, finalLevel + 1);

 94         }

 95         return result;

 96     }

 97 

 98     private void getPaths(String currentWord, ArrayList<String> list, int level) {

 99         if (currentWord.equals(end)) {

100             result.add(new ArrayList<String>(list));

101         } else if (level > 0) {

102             List<String> parentsSet = nextMap.get(currentWord);

103             for (String parent : parentsSet) {

104                 list.add(parent);

105                 getPaths(parent, list, level - 1);

106                 list.remove(list.size() - 1);

107             }

108         }

109     }

110 }

自己的解法还需要多想想:

 1 public class Solution {

 2     public ArrayList<ArrayList<String>> findLadders(String start, String end, Set<String> dict) {

 3         ArrayList<String> Ladder=new ArrayList<String>();

 4         ArrayList<ArrayList<String>> LadderList=new ArrayList<ArrayList<String>>();

 5         if(start.length() != end.length()) return LadderList;

 6         shortestladders(start, end, dict, Ladder, LadderList);

 7         return LadderList;

 8     }

 9     

10     public void shortestladders(String start, String end, Set<String> dict, ArrayList<String> Ladder, ArrayList<ArrayList<String>> LadderList){

11         Ladder.add(start);

12         if(within(start, end)) { //end is only 1 bit different from start

13             Ladder.add(end);

14             if(LadderList.isEmpty()) { //LadderList is empty, so Ladder is definately shortest

15                 LadderList.add(Ladder);

16             }

17             else { //LadderList is not empty, so need comparition

18                 ArrayList<String> shortestLadder = LadderList.get(0); // select one from LadderList

19                 if(Ladder.size() < shortestLadder.size()) { //new found Ladder is shorter than LadderList

20                     LadderList.clear();

21                     LadderList.add(Ladder);

22                 }

23                 else if(Ladder.size() == shortestLadder.size()) { //new found Ladder is the same with the LadderList,add to Ladderlist

24                     LadderList.add(Ladder);

25                 }

26                 // new found Ladder is longer than elems in LadderList, so do not change LadderList

27             }

28             Ladder.remove(Ladder.size()-1); //remove end

29         }

30         

31         else { //end is more than 1 bit different from start, so look for temp elems in dict which is 1 bit different from start

32             if(!dict.isEmpty()) {

33                 for(String temp:dict){

34                     if(within(start, temp)){

35                         dict.remove(start);

36                         shortestladders(temp, end, dict, Ladder, LadderList);

37                         dict.add(start);

38                     }

39                 }

40             }

41    

42         }

43         Ladder.remove(Ladder.size()-1); //remove start

44     }

45     

46     public boolean within(String first, String second){

47         int diff=0;

48         for(int k=0; k<first.length(); k++){

49             if(first.charAt(k)!=second.charAt(k)){

50                 diff++;

51             }

52         }

53         if(diff==1) return true;

54         else return false;

55     }

56 }

 

你可能感兴趣的:(LeetCode)