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]
andorder
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:]))