Categories
木有技术

LeetCode 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:

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

Example 3:

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

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.

 

Solution:

The solution is to build a directed map and find the topological ordering of the characters. Once the map is built, we can always find the “terminal” character which has no succeeding, i.e. the out-degree of that node would be zero. The we remove the character (the node and its edges) from the map and try to find the next such character, so on so forth.

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

For example,  the map built will be:

t: {f}
w: {e}
r: {t}
e: {r}
f: {}
class Solution {
private:
    map<char, set<char>> ch_map;
    void build(const string& w1, const string& w2)
    {
        const int len = std::min(w1.size(), w2.size());
        int i = 0;
        for (i = 0; i < len; ++i)
        {
            if (ch_map.count(w1[i]) == 0)
                ch_map[w1[i]] = set<char>();
            if (ch_map.count(w2[i]) == 0)
                ch_map[w2[i]] = set<char>();
            if (w1[i] != w2[i])
            {
                ch_map[w1[i]].insert(w2[i]);
                break;
            }
        }
        for (; i < w1.size() || i < w2.size(); ++i)
        {
            if (i < w1.size() && ch_map.count(w1[i]) == 0)
                ch_map[w1[i]] = set<char>();
            if (i < w2.size() && ch_map.count(w2[i]) == 0)
                ch_map[w2[i]] = set<char>();
        }
    }
public:
    string alienOrder(vector<string>& words) {
        if (words.empty()) return string();
        if (words.size() == 1) return words[0];
        for (int i = 0; i < words.size() - 1; ++i)
        {
            build(words[i], words[i+1]);
        }
        string result;
        result.reserve(26);
        while (!ch_map.empty())
        {
            bool found = false;
            for (auto it : ch_map)
            {
                if (it.second.empty())
                {
                    found = true;
                    result = it.first + result;
                    break;
                }
            }
            ch_map.erase(result[0]);
            if (!found) return string();  //not found
            for (auto& it : ch_map)
            {
                it.second.erase(result[0]);
            }
        }
        return result;
    }
};

 
 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.