【Leetcode】Word Ladder II - hardest

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) 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"]

Return

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

Note:

  • All words have the same length.

  • All words contain only lowercase alphabetic characters.
Java:
http://blog.csdn.net/linhuanmars/article/details/23071455
class StringWithLevel {
   String str;
   int level;
   public StringWithLevel(String str, int level) {
      this.str = str;
      this.level = level;
   }
}
public ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict) {
   ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
   HashSet<String> unvisitedSet = new HashSet<String>();
   unvisitedSet.addAll(dict);
   unvisitedSet.add(start);
   unvisitedSet.remove(end);
   Map<String, List<String>> nextMap = new HashMap<String, List<String>>();
   for (String e : unvisitedSet) {
      nextMap.put(e, new ArrayList<String>());
   }
   LinkedList<StringWithLevel> queue = new LinkedList<StringWithLevel>();
   queue.add(new StringWithLevel(end, 0));
   boolean found = false;
   int finalLevel = Integer.MAX_VALUE;
   int curLevel = 0;
   int preLevel = 0;
   HashSet<String> visitedCurLevel = new HashSet<String>();
   while (!queue.isEmpty()) {
      StringWithLevel cur = queue.poll();
      String curStr = cur.str;
      curLevel = cur.level;
      if(found && curLevel > finalLevel) {
         break;
      }
      if (curLevel > preLevel) {
         unvisitedSet.removeAll(visitedCurLevel);
      }
      preLevel = curLevel;
      char[] curStrCharArray = curStr.toCharArray();
      for (int i = 0; i < curStr.length(); ++i) {
         char originalChar = curStrCharArray[i];
         boolean foundCurCycle = false;
         for (char c = 'a'; c <= 'z'; ++c) {
            curStrCharArray[i] = c;
            String newStr = new String(curStrCharArray);
            if(c != originalChar && unvisitedSet.contains(newStr)) {
               nextMap.get(newStr).add(curStr);
               if(newStr.equals(start)) {
                  found = true;
                  finalLevel = curLevel;
                  foundCurCycle = true;
                  break;
               }
               if(visitedCurLevel.add(newStr)) {
                  queue.add(new StringWithLevel(newStr, curLevel + 1));
               }
            }
         }
         if(foundCurCycle) {
            break;
         }
         curStrCharArray[i] = originalChar;
     }
   }
   if(found) {
       ArrayList<String> list = new ArrayList<String>();
       list.add(start);
       getPaths(start, end, list, finalLevel + 1, nextMap, res);
   }
   return res;
}
private void getPaths(String cur, String end, ArrayList<String> list, int level, Map<String, List<String>> nextMap, ArrayList<ArrayList<String>> res) {
   if(cur.equals(end)){
      res.add(new ArrayList<String>(list));
   }
   else if(level > 0){
      List<String> parentsSet = nextMap.get(cur);
      for (String parent : parentsSet) {
         list.add(parent);
         getPaths(parent, end, list, level - 1, nextMap, res);
         list.remove(list.size() - 1);
      }
   }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值