LC 0953 [E] Verifying an Alien Dictionary - ALawliet/algorithms GitHub Wiki
intuitive? N
- build order hashmap of char => index for fast lookups
- loop zip pairs of word with adjacent word
w1, w2 in zip(words, words[1:])
- loop zip pairs of chars in the words
c1, c2 in zip(w1, w2)
check cases:
- chars are same => continue
- if not same, look up in order in hashmap => return False if chars not in order, break to next word for first one that is True
- prefix edge case: if no break (chars in shorter word exhausted) => return False if w1 does not come first because shorter word with blank should be lexico first, but use <= to check for same word because this should not return False
gotchas:
- if two words are the same ['hello', 'hello']
- if one word is exhausted early ['apple', 'app], ['kuvp', 'q']
T: O(C) where C is the total content in words
S: O(1)
class Solution:
def isAlienSorted(self, words, order):
d = {}
for i, c in enumerate(order):
d[c] = i
for w1, w2 in zip(words, words[1:]):
for c1, c2 in zip(w1, w2):
if c1 == c2: continue
# don't have to check <= because == handled by continue
if not d[c1] < d[c2]:
return False
else:
break # just have to check first pair of chars, then break to next word
else: # we exhausted all the characters in the shorter word with == and no failures
# now len of w1 must be shorter or at least the same
if not len(w1) <= len(w2):
return False
return True
class Solution:
def isAlienSorted(self, words, order):
# compare 2 words at a time
# compare 2 chars of each word at a time
# use a hashmap fast lookup order
d = {} # order_to_index
for i in range(len(order)):
d[order[i]] = i
print(d)
for w1, w2 in zip(words, words[1:]):
print(w1, w2)
for c1, c2 in zip(w1, w2):
print(c1, c2)
# if the chars are the same, skip this pair of chars and go to the next
if c1 == c2: continue # to next chars
# if they are not, then we are out of order
if not d[c1] < d[c2]: return False # can be < or <=
# else we are good, skip the rest of chars and go to next word
break # to next words
# if we skipped the chars cuz they passed, then just continue to the next word
# if we just finished looping (no breaks) thru all the chars of the shorter string, then check the lengths
else:
# we exhausted the shorter string from the loop, which should have been in the 1st position because blank < any other char
if not len(w1) <= len(w2): return False
# to next words
return True