zoukankan      html  css  js  c++  java
  • 269. Alien Dictionary


    June-27-2019

    比较难= = 用indegree的思路来做的,或者说拓扑的思路topological sort

    prevStr和tempStr,说明prevStr里的char在tempStr里的char之前.
    eg: abc&abd => d -> c 说明D前面有一个C

    要给所有出现的char建SET,记录前面有哪些char。 SET的大小代表char的indegree是几(前面有几个CHAR)
    上面的例子就这样 =>
    d : {c}

    遍历所有STR来比较,然后从indegree=0的开始删,和course schedule一个做法

    有问题的话会出现a的 set里有B, B的SET里有A,相互矛盾。

    有个隐藏条件
    "abc"
    "ab"
    是错的,空的永远排在任何字母之前,不容易想到,不用过分纠结这个。

    Time Complexity主要耗在遍历上 O(mn)

        public String alienOrder(String[] words) {
            
            Map<Character, Set<Character>> parentMap = new HashMap<>();
            
            for (String s : words) {
                for (char c : s.toCharArray()) {
                    if (!parentMap.containsKey(c)) {
                        parentMap.put(c, new HashSet<>());
                    }
                }
            }
            
            for (int i = 1; i < words.length; i ++) {
                String prevStr = words[i - 1];
                String tempStr = words[i];
                
                int len = Math.min(prevStr.length(), tempStr.length());
                for (int j = 0; j < len; j ++) {
                    char prevChar = prevStr.charAt(j);
                    char tempChar = tempStr.charAt(j);
                    
                    if (prevChar != tempChar) {                                     
                        if (!parentMap.get(tempChar).contains(prevChar)) {
                            parentMap.get(tempChar).add(prevChar);
                        }
                        break;
                    }
                    if (j == prevStr.length() - 1 && len + 1 == prevStr.length()) return "";
                }
                
            }
            
            ArrayDeque<Character> q = new ArrayDeque<>();
            for (Map.Entry<Character, Set<Character>> entry : parentMap.entrySet()) {
                if (entry.getValue().isEmpty()) {
                    q.offerLast(entry.getKey());
                }
            }
            
            StringBuilder sb = new StringBuilder();
            
            while (!q.isEmpty()) {
                char tempChar = q.pollFirst();
                parentMap.remove(tempChar);
                sb.append(tempChar);
                for (Map.Entry<Character, Set<Character>> entry : parentMap.entrySet()) {
                    if (entry.getValue().contains(tempChar)) {
                        entry.getValue().remove(tempChar);
                        if (entry.getValue().isEmpty()) {
                            q.offerLast(entry.getKey());
                        }
                    }
                }
            }
            
            if (parentMap.isEmpty()) {
                return sb.toString();
            } else {
                return "";
            }
            
        }
    

    =====================
    一刷。

    直接看的解法,大多数是用拓扑排序做的。

    说实话挺难的,直接看别人的CODE才理解。

    一开始也理解错了,单词里面的letter是没有顺序的,只是dictionary是按特殊顺序排列的。但是又不能只比较首字母,因为有可能首字母相同。

    Time: 假如26个字母。 不是很好算。。

    建图最差是N*N,但是这种情况发生时,整个图都是V,没有E。 就不用后面的拓扑排序了。拓扑排序是有边,才可以。。
    O(26²) + O(26) + O(26) * O(E) 大概这么个意思
    第一个26平方是建图,然后O(26)是入queue, O(26) * O(E)是拓扑排序。。

    这个题还有别的坑。

    "abc"
    "abcd"
    这样是没事的

    "abcd"
    "abc"
    这样是错的,‘ ’在‘d'之前是错的。
    有个rule没说,' ' shall before any letters,但是大家基本都以为Alien rule can be any rules it defines..= =

    public class Solution {
        public String alienOrder(String[] words) {
            if (words.length == 0) return "";
            
            Set<Character> letterSet = new HashSet<>();
            int[] inDegree = new int[26];
            Map<Character, HashSet<Character>> order = new HashMap<>();
            
            for (String s : words) {
                for (char c : s.toCharArray()) {
                    letterSet.add(c);
                }
            }
    
            for (int i = 1; i < words.length; i++) {
                String prevStr = words[i-1];
                String tempStr = words[i];
                
                if (prevStr.equals(tempStr)) continue;
                
                int len = Math.min(prevStr.length(), tempStr.length());
                
                for (int j = 0; j < len; j++) {
                    char prevC = prevStr.charAt(j);
                    char tempC = tempStr.charAt(j);
                    if (prevC != tempC) {
                        if (!order.containsKey(prevC)) {
                            order.put(prevC, new HashSet<>());
                        }
                        
                        if (!order.get(prevC).contains(tempC)) {
                            order.get(prevC).add(tempC);
                            inDegree[tempC - 'a'] ++;
                        }
                        break;
                    }
                    if (j == len - 1 && prevStr.length() > tempStr.length()) return "";
                }
            }
           
            
            Queue<Character> q = new LinkedList<>();
            for (int i = 0; i < inDegree.length; i++) {
                if (inDegree[i] == 0 && letterSet.contains((char)('a' + i))) {
                    q.offer((char)('a' + i));
                }
            }
            
            StringBuilder sb = new StringBuilder();
            while (!q.isEmpty()) {
                char tempChar = q.poll();
                sb.append(tempChar);
                if (order.containsKey(tempChar)) {
                    for (char c : order.get(tempChar)) {
                        inDegree[c - 'a'] --;
                        if (inDegree[c - 'a'] == 0) {
                            q.offer(c);
                        }
                    }
                }
            }
            
            if (sb.length() != letterSet.size()) {
                return "";
            } else {
                return sb.toString();
            }
        }
    }
    
  • 相关阅读:
    CREATE AGGREGATE
    技术文档列表
    jQuery 判断表单中多个 input text 中至少有一个不为空
    Java实现 蓝桥杯 算法提高 奥运会开幕式
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最大值路径
    Java实现 蓝桥杯 算法提高 最大值路径
    Java实现 蓝桥杯 算法提高 最大值路径
  • 原文地址:https://www.cnblogs.com/reboot329/p/6158858.html
Copyright © 2011-2022 走看看