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 "".

Note:

  1. You may assume all letters are in lowercase.
  2. You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
  3. If the order is invalid, return an empty string.
  4. There may be multiple valid order of letters, return any one of them is fine.

解题思路:

给了我们一个字典,字典是按照字母先后顺序排序的。

照这一点,我们可以寻找字母与字母之间的关系。

可以根据字典构建一个图,每个字母都是一个节点, 在前面的字母指向在后面的字母,这样可以构成一个有向图,那么我们要做的就是求这个图的拓扑排序。

1.构建图:

对字典中出现的每一个字母,初始化它的入度为0.

对字典中的每一个单词,我们用它与它后面一个单词相比较,找到第一个不相等的字母,将words[i][j]指向words[i+1][j](加入到邻接链表中),同时增加words[i+1][j]的入度。

2.拓扑排序:

现将入度为0的放入队列中

取出队首元素放入返回字符串中,根据邻接链表将其邻接点的入度减1,若此时邻接点的入度为0,则将该点加入队列。

3.检查是否有环:

若返回字符串的长度不等于indegree中节点的长度,则说明有环,清空ret。

代码:

class Solution {
public:
    string alienOrder(vector<string>& words) {
        string ret;
        unordered_map<char, vector<char>> graph;
        unordered_map<char, int> in_degree;
        for(auto w : words){
            for(auto c : w){
                in_degree[c] = 0;
            }
        }
        for(int i = 0; i < words.size()-1; i++){
            if(words[i][0] != words[i+1][0]){
                graph[words[i][0]].push_back(words[i+1][0]);
                in_degree[words[i+1][0]]++;
            }else{
                int j = 0;
                int len = min(words[i].size(), words[i+1].size());
                while(j < len && words[i][j] == words[i+1][j]) j++;
                if(j != len){
                    graph[words[i][j]].push_back(words[i+1][j]);
                    in_degree[words[i+1][j]]++;
                }
            }
        }
        queue<char> q;
        for(auto p : in_degree){
            if(p.second == 0) q.push(p.first);
        }
        while(!q.empty()){
            char cur = q.front();
            q.pop();
            ret.push_back(cur);
            if(graph.count(cur)){
                for(auto c : graph[cur]){
                    in_degree[c]--;
                    if(in_degree[c] == 0) q.push(c);
                }
            }
        }
        if(ret.size() != in_degree.size()) ret.clear();
        return ret;
        
    }
};

猜你喜欢

转载自www.cnblogs.com/yaoyudadudu/p/9293421.html
今日推荐