小明思考

          Just a software engineer
          posts - 124, comments - 36, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          字梯游戲II

          Posted on 2013-04-18 17:32 小明 閱讀(1372) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)結(jié)構(gòu)和算法
          問題給定兩個單詞(一個開始,一個結(jié)束)和一個字典,找出所有的最短的從開始單詞到結(jié)束單詞的變換的序列(可能不止一個),并滿足:

          1.每次只能變換一個字母
          2.所有的中間單詞必須存在于字典中

          比如:
          輸入:
          start = "hit"
          end = "cog"
          dict = ["hot","dot","dog","lot","log"]

          那么最短的變化序列有兩個
          ["hit","hot","dot","dog","cog"],
          ["hit","hot","lot","log","cog"]。
          注意:
          1. 所有單詞的長度都是相同的
          2. 所有單詞都只含有小寫的字母。

          分析:
          跟之前的字梯游戲相比,這個問題要求求出所有的最短序列,所以要使用一個Prev List來記錄前驅(qū)節(jié)點(可能不止一個)。這樣根據(jù)這個Prev List就可以遍歷出所有的最短組合。

          代碼如下:

          public class WordLadder2 {
              private List<List<Integer>> prev;
              private String[] allWords;

              private boolean canChange(String a, String b) {
                  int diff = 0;
                  int len = a.length();
                  for (int i = 0; i < len; ++i) {
                      if (a.charAt(i) != b.charAt(i)) {
                          ++diff;
                          if (diff > 1) {
                              return false;
                          }
                      }
                  }
                  return true;
              }

              private ArrayList<ArrayList<String>> perm(int node) {
                  ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
                  String current = allWords[node];
                  if (node == 0) {
                      ArrayList<String> as = new ArrayList<String>();
                      as.add(current);
                      result.add(as);
                  } else {
                      List<Integer> p = prev.get(node);
                      for (Integer pnode : p) {
                          ArrayList<ArrayList<String>> subResult = perm(pnode.intValue());
                          for (ArrayList<String> as : subResult) {
                              as.add(current);
                              result.add(as);
                          }
                      }
                  }
                  return result;
              }

              public ArrayList<ArrayList<String>> findLadders(String start, String end,
                      HashSet<String> dict) {
                  allWords = new String[dict.size() + 2];
                  int t = 0;
                  allWords[t++] = start;
                  for (String d : dict) {
                      allWords[t++] = d;
                  }
                  allWords[t++] = end;
                  int size = allWords.length;
                  boolean[][] matrix = new boolean[size][size];
                  for (int i = 0; i < size; ++i) {
                      String si = allWords[i];
                      for (int j = i + 1; j < size; ++j) {
                          String sj = allWords[j];
                          if (canChange(si, sj)) {
                              matrix[i][j] = matrix[j][i] = true;
                          }
                      }
                  }

                  int[] cost = new int[size];
                  prev = new ArrayList<List<Integer>>();
                  for (int i = 0; i < size; ++i) {
                      cost[i] = Integer.MAX_VALUE;
                      prev.add(new ArrayList<Integer>());
                  }
                  cost[0] = 0;
                  List<Integer> openlist = new ArrayList<Integer>();
                  openlist.add(0);
                  while (!openlist.isEmpty()) {
                      int current = openlist.remove(openlist.size() - 1);
                      boolean[] mn = matrix[current];
                      int cc = cost[current];
                      for (int i = 0; i < size; ++i) {
                          if (mn[i]) {
                              if (cost[i] > cc + 1) {
                                  cost[i] = cc + 1;
                                  prev.get(i).clear();
                                  prev.get(i).add(current);
                                  openlist.add(0, i);
                              } else if (cost[i] == cc + 1) {
                                  prev.get(i).add(current);
                              }
                          }
                      }
                  }

                  if (cost[size - 1] != Integer.MAX_VALUE) {
                      return perm(size - 1);
                  } else {
                      return new ArrayList<ArrayList<String>>();
                  }
              }
          }

          主站蜘蛛池模板: 永仁县| 浦北县| 万源市| 驻马店市| 齐河县| 无极县| 海原县| 龙海市| 保靖县| 盐山县| 安义县| 栖霞市| 涪陵区| 灵寿县| 葵青区| 库车县| 西畴县| 云安县| 安阳县| 厦门市| 泰顺县| 深水埗区| 沙雅县| 湘阴县| 多伦县| 桑日县| 安徽省| 麟游县| 苏尼特左旗| 洪雅县| 五寨县| 白河县| 梨树县| 昌平区| 延安市| 安图县| 洪泽县| 高安市| 吉安市| 太仓市| 兴山县|