小明思考

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

          字梯游戲II

          Posted on 2013-04-18 17:32 小明 閱讀(1370) 評論(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>>();
                  }
              }
          }

          主站蜘蛛池模板: 韶关市| 富川| 五寨县| 开原市| 天台县| 永年县| 兴义市| 临泉县| 荣昌县| 含山县| 海口市| 措勤县| 葫芦岛市| 米易县| 阳曲县| 兴国县| 淮阳县| 松江区| 大同县| 通道| 南木林县| 云林县| 德阳市| 垫江县| 浮梁县| 涞水县| 天峻县| 宜昌市| 抚松县| 蓬安县| 白山市| 凤翔县| 中牟县| 大埔区| 丰城市| 仙桃市| 乌苏市| 丹东市| 寿宁县| 鄂州市| 施甸县|