LeetCode #269 Alien Dictionary 火星詞典

269 Alien Dictionary 火星詞典

Description:

There is a new alien language that uses the English alphabet. However, the order among the letters is unknown to you.

You are given a list of strings words from the alien language's dictionary, where the strings in words are sorted lexicographically by the rules of this new language.

Return a string of the unique letters in the new alien language sorted in lexicographically increasing order by the new language's rules. If there is no solution, return "". If there are multiple solutions, return any of them.

A string s is lexicographically smaller than a string t if at the first letter where they differ, the letter in s comes before the letter in t in the alien language. If the first min(s.length, t.length) letters are the same, then s is smaller if and only if s.length < t.length.

Example:

Example 1:

Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"

Example 2:

Input: words = ["z","x"]
Output: "zx"

Example 3:

Input: words = ["z","x","z"]
Output: ""
Explanation: The order is invalid, so return "".

Constraints:

1 <= words.length <= 100
1 <= words[i].length <= 100
words[i] consists of only lowercase English letters.

題目描述:
現(xiàn)有一種使用英語字母的火星語言,這門語言的字母順序與英語順序不同。

給你一個字符串列表 words ,作為這門語言的詞典,words 中的字符串已經(jīng) 按這門新語言的字母順序進(jìn)行了排序 。

請你根據(jù)該詞典還原出此語言中已知的字母順序,并 按字母遞增順序 排列。若不存在合法字母順序,返回 "" 。若存在多種可能的合法字母順序,返回其中 任意一種 順序即可。

字符串 s 字典順序小于 字符串 t 有兩種情況:

在第一個不同字母處,如果 s 中的字母在這門外星語言的字母順序中位于 t 中字母之前,那么 s 的字典順序小于 t 。
如果前面 min(s.length, t.length) 字母都相同,那么 s.length < t.length 時,s 的字典順序也小于 t 。

示例:

示例 1:

輸入:words = ["wrt","wrf","er","ett","rftt"]
輸出:"wertf"

示例 2:

輸入:words = ["z","x"]
輸出:"zx"

示例 3:

輸入:words = ["z","x","z"]
輸出:""
解釋:不存在合法字母順序,因此返回 "" 。

提示:

1 <= words.length <= 100
1 <= words[i].length <= 100
words[i] 僅由小寫英文字母組成

思路:

拓?fù)渑判?br> 題意實際上需要保證出現(xiàn)在前面的字符在拓?fù)渑判蛑械奈恢酶壳?br> 先用 words 建立圖, 記錄下各個結(jié)點的后繼結(jié)點
注意這里如果出現(xiàn) "abc", "ab" 前后出現(xiàn)直接返回 ""
然后統(tǒng)計結(jié)點的入度
最后使用 BFS 拓?fù)渑判虻玫阶帜傅捻樞?br> 時間復(fù)雜度為 O(mn), 空間復(fù)雜度為 O(n), n 為 words 數(shù)組長度, m 為 words 中字符串的平均長度

代碼:

C++:

class Solution 
{
public:
    string alienOrder(vector<string>& words) 
    {
        map<char, unordered_set<char>> m;
        int n = words.size(), count = 0;
        vector<int> degree(26, -1);
        string result = "";
        for (int i = 0; i < n - 1; i++) 
        {
            for (int j = 0; j < min(words[i].size(), words[i + 1].size()); j++) 
            {
                if (words[i][j] != words[i + 1][j]) {
                    m[words[i][j]].insert(words[i + 1][j]);
                    break;
                } else if (j == min(words[i].size(), words[i + 1].size()) - 1 and words[i].size() > words[i + 1].size()) return result;
            }
        }
        for (const auto& word : words) for (const auto& c : word) degree[c - 'a'] = 0;
        for (const auto& [key, value] : m) for (const auto& v : m[key]) ++degree[v - 'a'];
        queue<char> q;
        for (int i = 0; i < 26; i++) 
        {
            if (!degree[i]) q.push((char)(i + 'a'));
            if (degree[i] != -1) ++count;
        }
        while (!q.empty()) 
        {
            auto u = q.front();
            q.pop();
            result += u;
            if (m.count(u)) 
            {
                for (const auto& v : m[u]) 
                {
                    --degree[v - 'a'];
                    if (!degree[v - 'a']) q.push(v);
                }
            }
        }
        return result.size() == count ? result : "";
    }
};

Java:

class Solution {
    public String alienOrder(String[] words) {
        Map<Character, Set<Character>> map = new HashMap<>();
        int n = words.length, degree[] = new int[26], count = 0;
        Arrays.fill(degree, -1);
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < Math.min(words[i].length(), words[i + 1].length()); j++) {
                if (words[i].charAt(j) != words[i + 1].charAt(j)) {
                    Set<Character> set = map.getOrDefault(words[i].charAt(j), new HashSet<>());
                    set.add(words[i + 1].charAt(j));
                    map.putIfAbsent(words[i].charAt(j), set);
                    break;
                } else if (j == Math.min(words[i].length(), words[i + 1].length()) - 1 && words[i].length() > words[i + 1].length()) return "";
            }
        }
        for (String word : words) for (char c : word.toCharArray()) degree[c - 'a'] = 0;
        for (Character key : map.keySet()) for (Character v : map.get(key)) ++degree[v - 'a'];
        StringBuilder sb = new StringBuilder();
        Queue<Character> queue = new LinkedList<>();
        for (int i = 0; i < 26; i++) {
            if (degree[i] == 0) queue.add((char)(i + 'a'));
            if (degree[i] != -1) ++count;
        }
        while (!queue.isEmpty()) {
            Character u = queue.poll();
            sb.append(u);
            if (map.containsKey(u)) {
                for (Character v : map.get(u)) {
                    --degree[v - 'a'];
                    if (degree[v - 'a'] == 0) queue.add(v);
                }
            }
        }
        return sb.length() == count ? sb.toString() : "";
    }
}

Python:

class Solution:
    def alienOrder(self, words: List[str]) -> str:
        graph, n, result, degree = defaultdict(set), len(words), '', [-1] * 26
        for i in range(n - 1):
            for j in range(min(len(words[i]), len(words[i + 1]))):
                if words[i][j] != words[i + 1][j]:
                    graph[words[i][j]].add(words[i + 1][j])
                    break
                elif j == min(len(words[i]), len(words[i + 1])) - 1 and len(words[i]) > len(words[i + 1]):
                    return result
        for word in words:
            for c in word:
                degree[ord(c) - ord('a')] = 0
        for key, value in graph.items():
            for v in graph[key]:
                degree[ord(v) - ord('a')] += 1
        q, count = deque([chr(i + ord('a')) for i in range(26) if not degree[i]]), sum(degree[i] != -1 for i in range(26))
        while q:
            u = q.popleft()
            result += u
            for v in graph[u]:
                degree[ord(v) - ord('a')] -= 1
                if not degree[ord(v) - ord('a')]:
                    q.append(v)
        return result if len(result) == count else ""
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容