zoukankan      html  css  js  c++  java
  • 每日一题 为了工作 2020 0420 第四十九题

    /**
     *
     * 【问题】字符串转换路径问题
     *         给定两个字符串,记为start和to,再给定一个字符串列表list,list中一定包含
     *         to,list中没有重复的字符串。所有字符串都是小写的。规定start每次只可以改
     *         变一个字符,最终的目标是彻底变成to,但每次变成的字符串都必须在list中存在。
     *         请返回最短的变换路径。
     * 【举例】
     *         start = "abc"
     *         to = "cab"
     *         list = {"cab","acc","cbc","ccc","cac","cbb","aab","abb"}
     *         转换路径的方法有很多种,但是最短的转换路径如下:
     *         abc --> abb --> aab --> cab
     *         abc --> abb --> cbb --> cab
     *         abc --> cbc --> cac --> cab
     *         abc --> cbc --> cbb --> cab
     * 【分析】
     *         本题目难度较大,需要拆分成四个步骤进行实现,接下来完成第一步骤获取每一个
     *         字符串的nexts信息。
     *
     * 【第一步】
     *         将start加入list,然后根据list生成每一个字符串的nexts信息。nexts具体是
     *         指如果朱改变一个字符,该字符串可以变成哪些字符串。比如上面的list,先把
     *         "abc"加入到list中,然后根据list生成信息如下:
     *         字符串    nexts信息(next要求属于list 否则丢弃)
     *         acc       abc ccc
     *         abb       aab cbb abc
     *         ccc       acc cac cbc
     *         cbb       abb cab cbc
     *         abc       abb cbc acc
     *         aab       abb cab
     *         cac       cbc cab ccc
     *         cab       aab cbb cac
     *         cbc       abc cac cbb ccc
     *
     *         如何判断生成的一个字符串是否在list内呢?
     *         首先把list中所有的字符串放入哈希表set中,这样检查某一个字符串是否在list中
     *         就可以通过查询set来实现,这样做的原因是哈希表查询的时间复杂度是O(1),比遍
     *         历list查询某个字符串是否在其中速度要快很多。
     *
     *         如何生成字符串的nexts信息呢?
     *         因为每一个字符都是小写,所以看"bcc" "ccc" "dcc" "ecc" ..."zcc"哪些在set中,
     *         就把哪些放到"acc"的nexts列表中;然后看"aac" "abc" "adc" "aec" ... "azc"哪些
     *         在set中,就把哪些放到"acc"的nexts列表中;最后看"aca" "acb" "acd" ... "acz"
     *         哪些在set中,就把哪些放到"acc"的nexts列表中。也就是说,某个位置的字符都是从
     *         a --> z 开始枚举,哪些在set中就放到该元素的nexts列表中。
     *
     * @author 雪瞳
     * @Slogan 时钟尚且前行,人怎能再次止步!
     * @Function 返回没一个字符串的next信息
     *
     */
    

      

    public class GetNexts {
        public HashMap<String,ArrayList<String>> getNexts(List<String> words){
            //将list放入哈希表内
            Set<String> dict =new HashSet<>(words);
            HashMap<String,ArrayList<String>> nexts = new HashMap<>();
    
            for (int i=0;i<words.size();i++){
                //给每一个元素创建一个nexts的kv映射 k为当前元素 v为该元素变换后的列表
                //列表初始为空
                nexts.put(words.get(i),new ArrayList<>());
            }
            for (int i=0;i<words.size();i++){
                //向列表内添加元素
                nexts.put(words.get(i),getNext(words.get(i),dict));
            }
            return nexts;
        }
        public ArrayList<String> getNext(String word, Set<String> dict){
            ArrayList<String> res = new ArrayList<>();
            //将每一个位置元素拆分成字符
            char[] chs = word.toCharArray();
            //对每一个位置都有26中字符改变
            for ( char cur = 'a'; cur <= 'z';cur++){
                for (int i=0;i<chs.length;i++){
                    //当前字符可以进行转换
                    if (chs[i] != cur){
                        char tmp = chs[i];
                        chs[i] = cur;
                        //判断转换后的字符串是否在哈希表中
                        if (dict.contains(String.valueOf(chs))){
                            res.add(String.valueOf(chs));
                        }
                        //将字符串复原 进行下一个位置的变换
                        chs[i]=tmp;
                    }
                }
            }
            return res;
        }
    
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            String[] elements = new String[]{"cab","acc","cbc","ccc","cac","cbb","aab","abb"};
            for (String elem : elements){
                list.add(elem);
            }
            GetNexts get = new GetNexts();
            HashMap<String, ArrayList<String>> nexts = get.getNexts(list);
            Set<Map.Entry<String, ArrayList<String>>> entries = nexts.entrySet();
            for (Map.Entry<String, ArrayList<String>> entry : entries){
                System.out.println(entry.getKey()+"----"+entry.getValue());
            }
        }
    }
    

      

    *运行结果

     

  • 相关阅读:
    洛谷 P1886 滑动窗口 (单调队列)
    Acwing 288.休息时间 (环形DP)
    Acwing 287.积蓄程度 (树形DP换根)
    2020 Multi-University Training Contest 5 Tree (树形DP)
    剑指offer-JZ50-数组中的重复数字(C++)
    假设以下有一个结构体存放的是学生的记录,每条记录包括:学号、姓名、成绩
    剑指offer-JZ48-不用加减乘除做加法(C++)
    剑指offer-JZ51-构建乘积数组
    数据结构与算法->递归
    力扣(LeetCode)试题6-Z字形变换 C++代码
  • 原文地址:https://www.cnblogs.com/walxt/p/12737275.html
Copyright © 2011-2022 走看看