• 单词接龙


    给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:

    每次转换只能改变一个字母。
    转换过程中的中间单词必须是字典中的单词。
    说明:

    如果不存在这样的转换序列,返回 0。
    所有单词具有相同的长度。
    所有单词只由小写字母组成。
    字典中不存在重复的单词。
    你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
    示例 1:

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

    输出: 5

    解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    返回它的长度 5。
    示例 2:

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

    输出: 0

    解释: endWord "cog" 不在字典中,所以无法进行转换。

    方法1: DFS

    • 使用队列广度搜索,时间复杂度为O(n^2*L)
    import java.util.*;
    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Queue<String> queue = new LinkedList<String>();
            boolean[] path = new boolean[wordList.size()];
            String temp;
            int len = 0;
            queue.add(beginWord);
            while(!queue.isEmpty()){
                int size = queue.size();
                while(size -- >0){
                    temp = queue.remove();
                    if(temp.equals(endWord)) return len+1;
                    for(int i = 0 ;i<wordList.size();i++){
                        String p = wordList.get(i);
                        if(isEquals(temp,p) && path[i]==false){
                            path[i] = true;
                            queue.add(p);
                        }
                    }
                }
                len++;
            }
            return 0;
        }
        public boolean isEquals(String x, String y){
            int count  = 0;
            for(int i = 0;i<y.length();i++){
                if(x.charAt(i) != y.charAt(i)){
                    count ++;
                }
                if(count>1) break;
            }
            return count <= 1;
        }
    }
    

    方法2:双向DFS

    • 使用双向DFS,从头尾两个方向向中间搜索,当两端搜索的集合包含重叠元素时,表示两端可以在该点连同。
    • 当第一次听说双向DFS,以为使用两个队列,但判断是否包含重叠元素时队列不好判断,所以使用Set容器比较方便。set每次保存搜索到的一层元素。
    • 对于头尾集合,保证每次都是从元素最少的集合中开始向下一层搜索,减少搜索时间。
    • 时间复杂度:每个元素都要放入set遍历一次,对于每个单词的每一位,都要用a-z替换一次,判断替换后的单词是否存在在另一个set中,hashset查询复杂度O(L),所以总的时间复杂度为 n26L^2

    算法流程:

    1. 构建头尾两个集合,保证头集合为元素最少的集合
    2. 从头集合开始搜索,当搜索到的元素在尾集合时,则说明已经到达,结束搜索
    3. 否则 将搜索到的元素放入新的头集合中,进行下一层搜索。
    import java.util.*;
    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Set<String> wordSet = new HashSet<>(wordList);
            Set<String> startSet = new HashSet<>();
            Set<String> endSet = new HashSet<>();
            startSet.add(beginWord);
            endSet.add(endWord);
            int len =  1;
            char[] ch;
            Set<String> temp;
            if(!wordSet.contains(endWord))  return 0;
            while(!startSet.isEmpty() && !endSet.isEmpty()){
                len ++;
                if(startSet.size() > endSet.size() ){
                    temp = endSet;
                    endSet = startSet;
                    startSet = temp;
                }
             //   System.out.print(startSet.toString());
             //   System.out.println(endSet.toString());
               Set<String> newhead = new HashSet<>();
                for(String p : startSet){
                    ch = p.toCharArray();
                    for(int i = 0;i < p.length();i++){
                        char k = ch[i];
                        for(char c = 'a';c <='z';c++){
                            if(c == k)  continue;
                            ch[i] = c;
                            String res = String.valueOf(ch);
                          //  System.out.println(res);
                            if(endSet.contains(res))
                                     return len;
                            if(wordSet.contains(res)){
                             //   System.out.println(res);
                                 wordSet.remove(res);
                                 newhead.add(res);
                            }
                        }
                        ch[i] = k;
                    }
                }
                startSet = newhead;
            }
            return 0;
        }
    }
    
  • 相关阅读:
    2017 ACM/ICPC Asia Regional Qingdao Online
    2017 ACM/ICPC Asia Regional Qingdao Online
    2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Sum
    2017 ACM/ICPC Asia Regional Shenyang Online array array array
    无权最短路
    解题报告:poj 3070
    矩阵学习笔记
    拓扑排序
    LIS严格递增和非递减模板
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A banana·
  • 原文地址:https://www.cnblogs.com/a1225234/p/11282821.html
Copyright © 2020-2023  润新知