zoukankan      html  css  js  c++  java
  • LeetCode 126. Word Ladder II

    原题链接在这里:https://leetcode.com/problems/word-ladder-ii/

    题目:

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

    1. Only one letter can be changed at a time
    2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

    For example,

    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log","cog"]

    Return

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

    Note:

    • Return an empty list if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.
    • You may assume no duplicates in the word list.
    • You may assume beginWord and endWord are non-empty and are not the same.

    题解:

    只需要打印出说有的最短路径. 当出现"最短"时自然想到BFS.

    Use BFS to construct a map. In this map, each word has corresponding set of next available words.

    When done with current set of words, need to remvoe them from set. Otherwise it would come back.

    再用DFS打印路径.

    Time Complexity: O(m*n). m = WordList.size(). n是平均word的长度. DFS 与BFS用时相似.

    Space: O(m).

    AC Java:

     1 class Solution {
     2     public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
     3         List<List<String>> res = new ArrayList<>();
     4         if(beginWord == null || endWord == null){
     5             return res;
     6         }
     7         
     8         HashSet<String> dic = new HashSet<>(wordList);
     9         if(!dic.contains(endWord)){
    10             return res;
    11         }
    12         
    13         HashMap<String, HashSet<String>> wordToCloest = new HashMap<>();
    14         HashSet<String> curSet = new HashSet<>();
    15         curSet.add(beginWord);
    16         bfs(curSet, endWord, wordToCloest, dic);
    17         
    18         List<String> item = new ArrayList<String>();
    19         item.add(beginWord);
    20         dfs(beginWord, endWord, wordToCloest, item, res);
    21         return res;
    22     }
    23     
    24     private void bfs(HashSet<String> curSet, String endWord, HashMap<String, HashSet<String>> wToClo, HashSet<String> dic){
    25         if(curSet == null || curSet.size() == 0){
    26             return;
    27         }
    28         
    29         dic.removeAll(curSet);
    30         boolean isEnd = false;
    31         HashSet<String> nextSet = new HashSet<>();
    32         for(String cur : curSet){            
    33             for(int i = 0; i < cur.length(); i++){
    34                 char [] arr = cur.toCharArray();
    35                 char ori = arr[i];
    36                 for(char c = 'a'; c <= 'z'; c++){
    37                     if(ori == c){
    38                         continue;
    39                     }
    40                     
    41                     arr[i] = c;
    42                     String can = new String(arr);
    43                     if(dic.contains(can)){
    44                         nextSet.add(can);
    45                         if(can.equals(endWord)){
    46                             isEnd = true;
    47                         }
    48                         
    49                         wToClo.putIfAbsent(cur, new HashSet<String>());
    50                         wToClo.get(cur).add(can);
    51                     }
    52                 }
    53             }
    54         }
    55         
    56         if(!isEnd){
    57             bfs(nextSet, endWord, wToClo, dic);
    58         }
    59     }
    60     
    61     private void dfs(String cur, String end, HashMap<String, HashSet<String>> wToClo, List<String> item, List<List<String>> res){
    62         if(cur.equals(end)){
    63             res.add(new ArrayList<String>(item));
    64             return;
    65         }
    66         
    67         HashSet<String> nexts = wToClo.getOrDefault(cur, new HashSet<String>());
    68         for(String next : nexts){
    69             item.add(next);
    70             dfs(next, end, wToClo, item, res);
    71             item.remove(item.size() - 1);
    72         }
    73     }
    74 }

    Here since endWord could also translate, we could use bidirectional BFS to optimize.

    When current set size is larger, reverse current set and end set to avoid intermidate set size is too big.

    Time Complexity: O(m*n).

    Space: O(m).

    AC Java:

     1 class Solution {
     2     public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
     3         List<List<String>> res = new ArrayList<>();
     4         Set<String> hs = new HashSet<String>(wordList);
     5         if(!hs.contains(endWord)){
     6             return res;
     7         }
     8         
     9         Map<String, Set<String>> map = new HashMap<>();
    10         Set<String> curSet = new HashSet<>();
    11         Set<String> endSet = new HashSet<>();
    12         curSet.add(beginWord);
    13         endSet.add(endWord);
    14         
    15         bfs(curSet, endSet, map, hs, false);
    16         
    17         List<String> item = new ArrayList<>();
    18         item.add(beginWord);
    19         dfs(beginWord, endWord, map, item, res);
    20         return res;
    21     }
    22     
    23     private void bfs(Set<String> curSet, Set<String> endSet, Map<String, Set<String>> map, Set<String> hs, boolean reverse){
    24         if(curSet.size() == 0){
    25             return;
    26         }
    27         
    28         if(curSet.size() > endSet.size()){
    29             bfs(endSet, curSet, map, hs, !reverse);
    30             return;
    31         }
    32         
    33         hs.removeAll(curSet);
    34         boolean findEnd = false;
    35         Set<String> nextSet = new HashSet<>();
    36         
    37         for(String cur : curSet){
    38             for(int i = 0; i<cur.length(); i++){
    39                 char [] charArr = cur.toCharArray();
    40                 char original = charArr[i];
    41                 for(char k = 'a'; k<='z'; k++){
    42                     if(k == original){
    43                         continue;
    44                     }
    45                     
    46                     charArr[i] = k;
    47                     String next = new String(charArr);
    48                     
    49                     
    50                     if(hs.contains(next)){
    51                         if(endSet.contains(next)){
    52                             findEnd = true;
    53                         }else{
    54                             nextSet.add(next);
    55                         }
    56                         
    57                         String key = reverse ? next : cur;
    58                         String value = reverse ? cur : next;
    59                         map.putIfAbsent(key, new HashSet<String>());
    60                         map.get(key).add(value);
    61                     }
    62                 }
    63             }
    64         }
    65         
    66         if(!findEnd){
    67             bfs(nextSet, endSet, map, hs, reverse);
    68         }
    69     }
    70     
    71     private void dfs(String curWord, String endWord, Map<String, Set<String>> map, List<String> item, List<List<String>> res){
    72         if(curWord.equals(endWord)){
    73             res.add(new ArrayList<String>(item));
    74             return;
    75         }
    76         
    77         Set<String> nextSet = map.getOrDefault(curWord, new HashSet<String>());
    78         for(String next : nextSet){
    79             item.add(next);
    80             dfs(next, endWord, map, item, res);
    81             item.remove(next);
    82         }
    83     }
    84 }

    类似Open the Lock.

  • 相关阅读:
    MyImages
    【优惠&正版】超级硬盘数据恢复软件(SuperRecovery)7.1正版注册码(39元一机终身授权,支持最新版)
    【2020年4月24日】TTradmin v2.3.2 简单好用的临时远程协助软件
    Radmin Center 1.54 测试版
    VS2015 编译原版 tightvnc 2.8.27 源码
    Centos 安装 Go 编译环境
    GHO文件安装到Vmware的两种姿势
    Radmin Server v3.5.2.1 汉化破解绿色版,完整版+精简版【20190505更新】
    系统服务监视、系统服务守护 ServiceMonitor
    API Monitor v2.0 Alpha-r13 (32+64) 汉化版
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4957857.html
Copyright © 2011-2022 走看看