zoukankan      html  css  js  c++  java
  • 269. Alien Dictionary火星语字典(拓扑排序)

    [抄题]:

    There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

    Example 1:

    Input:
    [
      "wrt",
      "wrf",
      "er",
      "ett",
      "rftt"
    ]
    
    Output: "wertf"
    

    Example 2:

    Input:
    [
      "z",
      "x"
    ]
    
    Output: "zx"
    

    Example 3:

    Input:
    [
      "z",
      "x",
      "z"
    ] 
    
    Output: "" 
    
    Explanation: The order is invalid, so return "".

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    相同的c2,只需要存一次(没有就新存 有就不存),反正如果存过 就必须退出了(返回一组即可 不用重复加)

    "["za","zb","ca","cb"]" How is this test case handled. 
    It should give out an empty string as the order can not be decided from the words given. but instead it returns "azbc". 回答:we can only now z-> c and a-> b so 'azbc' is right but right result is not limited to this only one. you can test 'zcab', 'abzc' are will all right as it is topological sort

    结果字符串长度不等于度数(不是不等于单词数)

    ["z","z"]的度数 = 字符串长度1
    正常,应该返回"z"而不是""

    [思维问题]:

    忘了拓扑排序用BFS怎么写了

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    DFS写拓扑排序似乎都很麻烦

    存点到点的对应关系,用map(其中的字符必须存成包装类Character,但是循环的时候可以写char)

            //存每个点的入度
            Map<char, Integer> degree = new HashMap<>();
            //存c1到c2...的对应关系
            Map<char, Set<char>> map = new HashMap<>();    

    [一句话思路]:

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. 出现index[i + 1]时,需要提前备注把上线变为n - 1

    [二刷]:

    1. BFS的时候别忘了吧把取出的c1添加到结果中去. 而且必须现有c1的key才能扩展。

    [三刷]:

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    c1 c2都要先判断一下有没有,再存

    [复杂度]:Time complexity: O(n^2 单词数*字母数) Space complexity: O(n)

    [算法思想:递归/分治/贪心]:

    [关键模板化代码]:

    BFS的存储和扩展是两个独立的步骤,扩展时必须先判断key是否存在,再做扩展

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

    class Solution {
        public String alienOrder(String[] words) {
            //ini:HashMap<Char, Integer> degree, store all chars into hashmap, String res
            //存每个点的入度
            Map<Character, Integer> degree = new HashMap<>();
            //存c1到c2...的对应关系
            Map<Character, Set<Character>> map = new HashMap<>();
            String res = "";
            for (String word : words) {
                for (char c : word.toCharArray()) 
                    degree.put(c, 0);
            }
            
            //compare and store, n - 1
            for (int i = 0; i < words.length - 1; i++) {
                String cur = words[i];
                String next = words[i + 1];
                int smallerLen = Math.min(cur.length(), next.length());
                
                for (int j = 0; j < smallerLen; j++) {
                    char c1 = cur.charAt(j);
                    char c2 = next.charAt(j);
                    
                    if (c1 != c2) {
                        //new set
                        Set<Character> set = new HashSet<>();
                        //contains c1
                        if (map.containsKey(c1)) set = map.get(c1);
                        
                        //not contain c2
                        if (!set.contains(c2)) {
                            set.add(c2);
                            map.put(c1, set);
                            degree.put(c2, degree.get(c2) + 1);
                        }
                        break;
                    }
                }
            }
            
            //bfs, get answer
            Queue<Character> q = new LinkedList<>();
            for (char c : degree.keySet()) {
                if (degree.get(c) == 0) q.offer(c);
            }
            
            
            while (!q.isEmpty()) {
                char c1 = q.remove();
                res += c1;
                if (map.containsKey(c1)) {
                    for (char c2 : map.get(c1)) {
                    degree.put(c2, degree.get(c2) - 1);
                    if (degree.get(c2) == 0) q.offer(c2);
                }
                }
            }
            
            //cc at end
            if (res.length() != degree.size()) return "";
            
            return res;
    }
    }
    View Code
  • 相关阅读:
    226_翻转二叉树
    199_二叉树的右视图
    145_二叉树的后序遍历
    做IT,网络/系统/数据库/软件开发都得懂
    [恢]hdu 1200
    [恢]hdu 2080
    [恢]hdu 1222
    [恢]hdu 1128
    [恢]hdu 2153
    [恢]hdu 2132
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9091946.html
Copyright © 2011-2022 走看看