EXAMPLE
Input: DAMP, LIKE
Output: DAMP -> LAMP -> LIMP -> LIME -> LIKEjava
思路:c++
這其實就是廣度優先遍歷。遍歷過程當中,咱們須要記錄路徑,在找到目標單詞後,根據記錄的路徑打印出變形過程。app
BFS的變形體。對起始單詞的每個字母都作替換,把替換後的單詞加入到queue中,並同時維護一個Map來記錄變化前單詞和變化後單詞的聯繫。用來回溯時能打印出路徑。spa
[java] view plain copy.net
- package Hard;
-
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.Map;
- import java.util.Queue;
- import java.util.Set;
- import java.util.TreeMap;
- import java.util.TreeSet;
-
-
- /**
- * Given two words of equal length that are in a dictionary, write a method to trans-
- form one word into another word by changing only one letter at a time. The new
- word you get in each step must be in the dictionary.
-
- 給定兩個有着相同長度且都在字典內的單詞,要求寫一個方法來把一個單詞變型成另外一個單詞。
- 一次只能轉換一個字母,且每次生成的單詞必須在字典內
- *
- */
- public class S18_10 {
-
- public static LinkedList<String> transform(String startWord, String stopWord, Set<String> dictionary) {
- startWord = startWord.toUpperCase();
- stopWord = stopWord.toUpperCase();
- Queue<String> actionQueue = new LinkedList<String>();
- Set<String> visitedSet = new HashSet<String>();
- Map<String, String> backtrackMap = new TreeMap<String, String>();
-
- actionQueue.add(startWord);
- visitedSet.add(startWord);
-
- while (!actionQueue.isEmpty()) {
- String w = actionQueue.poll();
- // For each possible word v from w with one edit operation
- for (String v : getOneEditWords(w)) {
- if (v.equals(stopWord)) { // Found our word! Now, back track.
- LinkedList<String> list = new LinkedList<String>();
- list.add(v); // Append v to list
- while (w != null) {
- list.add(0, w);
- w = backtrackMap.get(w);
- }
- return list;
- }
-
- // If v is a dictionary word
- if (dictionary.contains(v)) {
- if (!visitedSet.contains(v)) {
- actionQueue.add(v);
- visitedSet.add(v); // mark visited
- backtrackMap.put(v, w); // w is the previous state of v
- }
- }
- }
- }
- return null;
- }
-
- // 改變word的某一個字母
- private static Set<String> getOneEditWords(String word) {
- Set<String> words = new TreeSet<String>();
-
- for (int i = 0; i < word.length(); i++) { // for every letter
- char[] wordArray = word.toCharArray();
- // change that letter to something else
- for (char c = 'A'; c <= 'Z'; c++) {
- if (c != word.charAt(i)) {
- wordArray[i] = c;
- words.add(new String(wordArray));
- }
- }
- }
- return words;
- }
-
- public static HashSet<String> setupDictionary(String[] words) {
- HashSet<String> hash = new HashSet<String>();
- for (String word : words) {
- hash.add(word.toUpperCase());
- }
- return hash;
- }
-
- public static void main(String[] args) {
- String[] words = { "maps", "tan", "tree", "apple", "cans", "help",
- "aped", "free", "apes", "flat", "trap", "fret", "trip", "trie",
- "frat", "fril" };
- HashSet<String> dict = setupDictionary(words);
- LinkedList<String> list = transform("tree", "flat", dict);
- for (String word : list) {
- System.out.println(word);
- }
- }
- }