1. 程式人生 > >Leetcode 953:驗證外星語詞典(超詳細的解法!!!)

Leetcode 953:驗證外星語詞典(超詳細的解法!!!)

某種外星語也使用英文小寫字母,但可能順序 order 不同。字母表的順序(order)是一些小寫字母的排列。

給定一組用外星語書寫的單詞 words,以及其字母表的順序 order,只有當給定的單詞在這種外星語中按字典序排列時,返回 true;否則,返回 false

示例 1:

輸入:words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz"
輸出:true
解釋:在該語言的字母表中,'h' 位於 'l' 之前,所以單詞序列是按字典序排列的。

示例 2:

輸入:words = ["word","world","row"], order = "worldabcefghijkmnpqstuvxyz"
輸出:false
解釋:在該語言的字母表中,'d' 位於 'l' 之後,那麼 words[0] > words[1],因此單詞序列不是按字典序排列的。

示例 3:

輸入:words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz"
輸出:false
解釋:當前三個字元 "app" 匹配時,第二個字串相對短一些,然後根據詞典編纂規則 "apple" > "app",因為 'l' > '∅',其中 '∅' 是空白字元,定義為比任何其他字元都小(更多資訊)。 

提示:

  1. 1 <= words.length <= 100
  2. 1 <= words[i].length <= 20
  3. order.length == 26
  4. words[i]
    order 中的所有字元都是英文小寫字母。

解題思路

最簡單的思路就是通過sorted函式裡面的cmp函式屬性,但是在python3中移除了這個東西,但是可以使用cmp_to_key替代。

from functools import cmp_to_key
class Solution:
    def isAlienSorted(self, words, order):
        """
        :type words: List[str]
        :type order: str
        :rtype: bool
        """
        words_dict =
{c: i for i, c in enumerate(order)} def helper(x, y): nonlocal words_dict x_len, y_len = len(x), len(y) i, j = 0, 0 while i < x_len and j < y_len: if x[i] == y[j]: i += 1 j += 1 continue if words_dict[x[i]] < words_dict[y[j]]: return -1 if words_dict[x[i]] > words_dict[y[j]]: return 1 if i == x_len and j == y_len: return 0 if i < x_len: return 1 if j < y_len: return -1 return words == sorted(words, key=cmp_to_key(lambda x, y:helper(x, y)))

我們這裡使用了一個dict去儲存我們的order中的字母順序,這樣做的好處就是比我們直接使用index這個內建函式方法快上許多。對於例1就是

我們還有一種更加簡潔的寫法。

class Solution:
    def isAlienSorted(self, words, order):
        """
        :type words: List[str]
        :type order: str
        :rtype: bool
        """
        return words == sorted(words, key=lambda x: list(map(order.index, x)))

我們也可以不同排序,直接比較字元對應的數字即可(實際上和第一種方式一樣,只是我們現在的實現方式更加的pythonic)。

class Solution:
    def isAlienSorted(self, words, order):
        """
        :type words: List[str]
        :type order: str
        :rtype: bool
        """
        order = {c:i for i, c in enumerate(order)}
        
        for word1, word2 in zip(words, words[1:]):
            for a,b in zip(word1, word2):
                if a != b:
                    if order[a] > order[b]:
                        return False
                    break
            else:
                if len(word1) > len(word2):
                    return False
        return True

我們也可以將words中的單詞,通過我們建立的dict替換為對應的數字。例如對於例1中的hello,我們可以替換為

我們只要比較替換後字串即可。
class Solution:
    def isAlienSorted(self, words, order):
        """
        :type words: List[str]
        :type order: str
        :rtype: bool
        """
        m = {c: i for i, c in enumerate(order)}
        words = [[m[c] for c in w] for w in words]
        return all(w1 <= w2 for w1, w2 in zip(words, words[1:]))

reference:

https://leetcode.com/problems/verifying-an-alien-dictionary/discuss/203185/JavaC++Python-Mapping-to-Normal-Order

我將該問題的其他語言版本新增到了我的GitHub Leetcode

如有問題,希望大家指出!!!