IT技術小屋

          秋風秋雨,皆入我心

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            38 隨筆 :: 1 文章 :: 19 評論 :: 0 Trackbacks
          Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
              1. Only one letter can be changed at a time
              2. Each intermediate word must exist in the dictionary
          For example,
          Given:
              start = "hit"
              end = "cog"
              dict = ["hot","dot","dog","lot","log"]
              As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
              return its length 5.
          Note:
              1. Return 0 if there is no such transformation sequence.
              2. All words have the same length.
              3. All words contain only lowercase alphabetic characters.

          第一個思路是遍歷dict中的每一個元素,看是不是和當前word只相差一個字符,如果是則作為新的當前word,直到當前word與target只相差一個字符。實現代碼如下:
           1 public class Solution {
           2     public int ladderLength(String start, String end, HashSet<String> dict) {
           3         HashSet<String> trash = new HashSet<String>();
           4         return searchWordLadder(start, end, dict, trash) + 1;
           5     }
           6 
           7     private int searchWordLadder(String start, String end, HashSet<String> dict, HashSet<String> trash) {
           8         if (stringDiff(start, end) == 1) return 1;
           9         if (dict.size() == trash.size()) return 0;
          10         int steps = Integer.MAX_VALUE;
          11         for (String word : dict) {
          12             if (!trash.contains(word) && stringDiff(start, word) == 1) {
          13                 trash.add(word);
          14                 int lt = searchWordLadder(word, end, dict, trash);
          15                 if (lt != 0 && lt < steps) {
          16                     steps = lt;
          17                 }
          18                 trash.remove(word);
          19             }
          20         }
          21         return steps == Integer.MAX_VALUE ? 0 : steps + 1;
          22     }
          23     
          24     private int stringDiff(String s1, String s2) {
          25         int diff = 0;
          26         int length = s1.length();
          27         for (int i = 0; i < length; i++) {
          28             if (s1.charAt(i) != s2.charAt(i)) {
          29                 diff++;
          30             }
          31         }
          32         return diff;
          33     }
          34 }
          這個算法可以通過小數據測試,但是在大數據下報超時錯誤。主要問題是算法復雜度較高,由于dict中的單詞是亂序的,因此最壞情況下需要遍歷所有可能的轉換路徑才能做出判斷。
          改變思路,其實可以通過trie樹的BFS搜索獲得結果,由于BFS是分層遍歷的,因此找到一個解之后就可以馬上返回,復雜度是O(N),N是原單詞的長度。實現代碼如下:
           1 public class WordLadder {
           2     public int ladderLength(String start, String end, HashSet<String> dict) {
           3         if (dict.size() == 0)
           4             return 0;
           5         int currentLevel = 1;
           6         int nextLevel = 0;
           7         int step = 1;
           8         boolean found = false;
           9         Queue<String> st = new LinkedList<String>();
          10         HashSet<String> visited = new HashSet<String>();
          11         st.add(start);
          12         while (!st.isEmpty()) {
          13             String s = st.remove();
          14             currentLevel--;
          15             if (stringDiff(s, end) == 1) {
          16                 found = true;
          17                 step++;
          18                 break;
          19             } else {
          20                 int length = s.length();
          21                 StringBuffer sb = new StringBuffer(s);
          22                 for (int i = 0; i < length; i++) {
          23                     for (int j = 0; j < 26; j++) {
          24                         char c = sb.charAt(i);
          25                         sb.setCharAt(i, (char) ('a' + j));
          26                         if (dict.contains(sb.toString())
          27                                 && !visited.contains(sb.toString())) {
          28                             nextLevel++;
          29                             st.add(sb.toString());
          30                             visited.add(sb.toString());
          31                         }
          32                         sb.setCharAt(i, c);
          33                     }
          34                 }
          35             }
          36             if (currentLevel == 0) {
          37                 currentLevel = nextLevel;
          38                 nextLevel = 0;
          39                 step++;
          40             }
          41         }
          42         return found ? step : 0;
          43     }
          44 
          45     private int stringDiff(String s1, String s2) {
          46         int diff = 0;
          47         int length = s1.length();
          48         for (int i = 0; i < length; i++) {
          49             if (s1.charAt(i) != s2.charAt(i)) {
          50                 diff++;
          51             }
          52         }
          53         return diff;
          54     }
          55 }
          其中利用了隊列對trie樹進行BFS。
          posted on 2013-12-19 09:11 Meng Lee 閱讀(1531) 評論(0)  編輯  收藏 所屬分類: Leetcode
          主站蜘蛛池模板: 平谷区| 霍林郭勒市| 华蓥市| 五莲县| 炎陵县| 监利县| 定兴县| 丰原市| 隆子县| 睢宁县| 神农架林区| 东城区| 大丰市| 崇义县| 石棉县| 连平县| 蒲江县| 韶关市| 孝感市| 宝应县| 濉溪县| 黑河市| 大名县| 南华县| 阿克陶县| 永靖县| 田林县| 虹口区| 庆城县| 吉安市| 游戏| 邹平县| 黄龙县| 东源县| 大埔区| 鞍山市| 安远县| 万年县| 台北县| 孝义市| 克山县|