[LeetCode] 953. Verifying an Alien Dictionary 驗證外星文字典



In an alien language, surprisingly they also use english lowercase letters, but possibly in a different order. The order of the alphabet is some permutation of lowercase letters.

Given a sequence of words written in the alien language, and the order of the alphabet, return true if and only if the given words are sorted lexicographicaly in this alien language.

Example 1:

Input: words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz"
Output: true
Explanation: As 'h' comes before 'l' in this language, then the sequence is sorted.

Example 2:

Input: words = ["word","world","row"], order = "worldabcefghijkmnpqstuvxyz"
Output: false
Explanation: As 'd' comes after 'l' in this language, then words[0] > words[1], hence the sequence is unsorted.

Example 3:

Input: words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz"
Output: false
Explanation: The first three characters "app" match, and the second string is shorter (in size.) According to lexicographical rules "apple" > "app", because 'l' > '∅', where '∅' is defined as the blank character which is less than any other character ([More info](https://en.wikipedia.org/wiki/Lexicographical_order)).

Constraints:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 20
  • order.length == 26
  • All characters in words[i] and order are English lowercase letters.

這道題說是有一個外星文字典,其字母順序和英語中的字母順序不同,但還是使用原來的 26 個字母,現在給了這個外星文的字典順序,又給了一個單詞數組,問這些單詞是否是按字母順序排列的。對於正常的字母順序,就是按字母來比較,只要有字母不同的話,就可以知道兩個單詞的順序了,假如比較的字母均相同,但是有一個單詞提前結束了,而另一個單詞后面還有字母,則短的那個單詞排前面。整體比較的思路仍然相同,就是字母順序要用其給定的順序,所以用一個 HashMap 來建立字母和其對應位置之間的映射,這樣在比較字母順序的時候就可以從 HashMap 中直接取值。在驗證順序的時候,只需要兩兩進行驗證,若某一對的順序不符合,則直接返回 false。具體的比較方法還是跟之前說的,逐個字母進行比較,為了避免越界,遍歷的時候只能遍歷到二者中較短的長度。若對應位上的字母相同,則直接跳過;若前面的字母順序靠后,則直接返回 false,否則 break 掉(注意這里不能直接返回 true 的原因是后面有可能還會出現不合題目要求的情況)。之后還要驗證前面提到的一種情況,就是當較短的單詞是較長單詞的子串時,而且后面的單詞較短時,也需要返回 false。當外層 for 循環正常退出后,返回 true 即可,參見代碼如下:


解法一:

class Solution {
public:
    bool isAlienSorted(vector<string>& words, string order) {
        unordered_map<char, int> charMap;
        for (int i = 0; i < order.size(); ++i) {
            charMap[order[i]] = i;
        }
        for (int i = 1; i < words.size(); ++i) {
            string word1 = words[i - 1], word2 = words[i];
            int n1 = word1.size(), n2 = word2.size();
            for (int j = 0; j < n1 && j < n2; ++j) {
                if (word1[j] == word2[j]) continue;
                if (charMap[word1[j]] > charMap[word2[j]]) return false;
                else break;
            }
            if (n1 > n2 && word1.substr(0, n2) == word2) return false;
        }
        return true;
    }
};

再來看一種比較巧妙的方法,調用了 STL 內部的 is_sorted 函數,由於這個函數是針對正常的字母順序的,所以要根據外星文的順序來調換 words 中的字母,使其變為對應的正常的字母順序。是不是不太好理解,比如外星文的順序是 bac,則b對應0,a對應1,c對應2,現在給兩個單詞,ba 和 ac,一眼可以看出這不符合正常的字母順序,但是其符合外星文的順序,所以要將其轉化為 01 和 12,這里不是數字,而是當作 ASCII 碼,跟表示字母的一樣,此時再比較的話就是正常的字母順序了,完美解決,參見代碼如下:


解法二:

class Solution {
public:
    bool isAlienSorted(vector<string>& words, string order) {
        vector<int> charMap(26);
        for (int i = 0; i < order.size(); ++i) {
            charMap[order[i] - 'a'] = i;
        }
        for (string &word : words) {
            for (char &c : word) {
                c = charMap[c - 'a'];
            }
        }
        return is_sorted(words.begin(), words.end());
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/953


參考資料:

https://leetcode.com/problems/verifying-an-alien-dictionary/

https://leetcode.com/problems/verifying-an-alien-dictionary/discuss/203185/JavaC%2B%2BPython-Mapping-to-Normal-Order

https://leetcode.com/problems/verifying-an-alien-dictionary/discuss/203246/JavaPython-3-Clean-codes-w-comment-time%3A-O(mn)-space%3A-O(1).


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM