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 lexicographically 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).

Constraints:

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

Solution1:

  • Hash indexes of each character for better runtime
  • Compare every adjacent word
  • If any letter of former word is in higher order, return False
  • If current letter of former word is in lower order, forget the rest of word
  • If lenght of former word is longer and latter word is substring of former, return False (apple & app etc.)
  • Return True
class Solution:
    def isAlienSorted(self, words, order):
        ind = {c: i for i, c in enumerate(order)}
        for a, b in zip(words, words[1:]):
            if len(a) > len(b) and a[:len(b)] == b:
                return False
            for s1, s2 in zip(a, b):
                if ind[s1] < ind[s2]:
                    break
                elif ind[s1] > ind[s2]:
                    return False
        return True

A similar idea without using the hash index map:

class Solution:
class Solution:
    def isAlienSorted(self, words, order):
        
        for a, b in zip(words, words[1:]):
            i, j, A, B = 0, 0, len(a), len(b)

            while i < A and j < B:
                aOrderIdx = order.index(a[i])
                bOrderIdx = order.index(b[i])
                if aOrderIdx == bOrderIdx:
                    i += 1
                    j += 1
                elif aOrderIdx > bOrderIdx:
                    return False
                else:
                    break

            if i < A and j == B:
                return False
            
        return True

Solution2:

Explanation

Build a transform mapping from order,
Find all alien words with letters in normal order.

For example, if we have order = "xyz..."
We can map the word "xyz" to "abc" or "123"

Then we check if all words are in sorted order.

Complexity

Time O(NS)
Space O(1)

class Solution:
    def isAlienSorted(self, words, order):
        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:]))

Leave a Comment

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

Scroll to Top