<Topological Sort> ( 高频, hard) 269

269Alien Dictionary

这些就是有向图的边,对于有向图中的每个结点,计算其入度,然后从入度为0的结点开始 BFS 遍历这个有向图,然后将遍历路径保存下来返回即可。下面来看具体的做法:

根据之前讲解,需用 TreeSet 来保存这些 pair,我们还需要一个 HashSet 来保存所有出现过的字母,需要一个一维数组 in 来保存每个字母的入度,另外还要一个 queue 来辅助拓扑遍历,我们先遍历单词集,把所有字母先存入 HashSet,然后我们每两个相邻的单词比较,找出顺序 pair,然后我们根据这些 pair 来赋度,我们把 HashSet 中入度为0的字母都排入 queue 中,然后开始遍历,如果字母在 TreeSet 中存在,则将其 pair 中对应的字母的入度减1,若此时入度减为0了,则将对应的字母排入 queue 中并且加入结果 res 中,直到遍历完成。

最后看结果 sb 和 map.size() 中的元素个数是否相同,若不相同则说明可能有环存在,返回空字符串

Map<out, in>

class Solution {
    public String alienOrder(String[] words) {
        int[] indegree = new int[26];
        Map<Character, Set<Character>> g = new HashMap<>();
        buildGraph(g, words, indegree);
        return bfs(g, indegree);
    }
    
    private void buildGraph(Map<Character, Set<Character>> g, String[] words, int[] indegree){
        for(String word : words){
            for(char c : word.toCharArray()){
                g.putIfAbsent(c, new HashSet<>());
            }
        }
        
        for(int i = 1; i < words.length; i++){
            String first = words[i - 1];
            String second = words[i];
            int len = Math.min(first.length(), second.length());
            for(int j = 0; j < len; j++){
                if(first.charAt(j) != second.charAt(j)){
                    char out = first.charAt(j);
                    char in = second.charAt(j);
                    if(!g.get(out).contains(in)){
                        g.get(out).add(in);
                        indegree[in - 'a']++;
                    }
                    break;
                }
            }
        }
    }
    
    private String bfs(Map<Character, Set<Character>> g, int[] indegree){
        StringBuilder sb = new StringBuilder();
        int totalChars = g.size();
        Queue<Character> q = new LinkedList<>();
        for(char c : g.keySet()){
            if(indegree[c - 'a'] == 0){
                sb.append(c);
                q.offer(c);
            }
        }
        
        while(!q.isEmpty()){
            char out = q.poll();
            if(g.get(out) == null || g.get(out).size() == 0) continue;
            for(char in : g.get(out)){
                indegree[in - 'a']--;
                if(indegree[in - 'a'] == 0){
                    q.offer(in);
                    sb.append(in);                    
                }
            }
        }
        return sb.length() == totalChars ? sb.toString() : "";
    }
}

269Alien Dictionary

原文地址:https://www.cnblogs.com/Afei-1123/p/12044470.html