拓扑排序关键:

  1. 无环有向图Directed Acyclic Graph (DAG)
  2. 用backtracking或stack从后往前
  3. 记录访问过的节点避免重复访问

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 ofnon-emptywords from the dictionary, wherewords are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

Example 1:
Given the following words in dictionary,

[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]

The correct order is:"wertf".

Example 2:
Given the following words in dictionary,

[
  "z",
  "x"
]

The correct order is:"zx".

Example 3:
Given the following words in dictionary,

[
  "z",
  "x",
  "z"
]

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.

S: Topological Sort

  1. 根据前后两个单词第一个不同的字母构建有向边,从而组成图。注意无序节点也要加入图
  2. 对图进行拓扑排序,用visited记录访问过的节点,用ancestor记录当前路径的前后关系判断是否成环
class Solution {
public:
    string alienOrder(vector<string>& words) {
        if (words.size() == 1) {
            return words[0];
        }
        unordered_map<char, unordered_set<char>> map;
        for (int i = 1; i < words.size(); ++i) {
            makeGraph(map, words[i - 1], words[i]);
        }
        vector<bool> visited(26);
        vector<bool> ancestor(26);
        string result = "";
        string test = "";
        for (const auto& i : map) {
            test += i.first;
            if (!dfs(map, i.first, result, visited, ancestor)){
                return "";
            }
        }
        return result;
    }

private:
    void makeGraph(unordered_map<char, unordered_set<char>>& map, string word1, string word2) {
        int idx = 0;
        while (idx < word1.size() && idx < word2.size() && word1[idx] == word2[idx]) {
            addChar(map, word1[idx]);
            idx++;
        }
        if (idx < word1.size() && idx < word2.size()) {
            map[word1[idx]].insert(word2[idx]);
            addChar(map, word2[idx]);
            idx++;
        }
        for (int i = idx; i < word1.size(); ++i) {
            addChar(map, word1[idx]);
        }
        for (int i = idx; i < word2.size(); ++i) {
            addChar(map, word2[idx]);
        }
    }
    void addChar(unordered_map<char, unordered_set<char>>& map, char a) {
        if (map.find(a) == map.end()) {
            map[a] = unordered_set<char>{};
        }
    }
    bool dfs(unordered_map<char, unordered_set<char>>& map, char letter, string& result, 
             vector<bool>& visited, vector<bool>& ancestor) {
        if (ancestor[letter - 'a']) {
            return false;
        }
        if (visited[letter - 'a']) {
            return true;
        }
        visited[letter - 'a'] = true;
        ancestor[letter - 'a'] = true;
        for (char i : map[letter]) {
            if (!dfs(map, i, result, visited, ancestor)) {
                return false;
            }
        }
        ancestor[letter - 'a'] = false;
        result = letter + result;
        return true;
    }
};

results matching ""

    No results matching ""