Verifying an Alien Dictionary
Are the words sorted in the given alien order? Pairwise compare via rank map.
4 min read
topological-sort string
Problem#
Given words and an alien order string, return true iff words is sorted according to that order.
Examples#
words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz"→truewords = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz"→false
Constraints#
1 <= words.length <= 100.
Approach#
Build rank[c] = position of c in order. For each adjacent word pair, compare character ranks at the first differing position; if no difference within shorter length, the shorter must precede.
Solution#
class Solution {public: bool isAlienSorted(vector<string>& words, string order) { int rank[26]; for (int i = 0; i < 26; ++i) rank[order[i] - 'a'] = i; for (int i = 0; i + 1 < (int)words.size(); ++i) { const string& a = words[i]; const string& b = words[i + 1]; int n = min(a.size(), b.size()), j = 0; for (; j < n && a[j] == b[j]; ++j) {} if (j == n) { if (a.size() > b.size()) return false; } else if (rank[a[j] - 'a'] > rank[b[j] - 'a']) return false; } return true; }};func isAlienSorted(words []string, order string) bool { var rank [26]int for i := 0; i < 26; i++ { rank[order[i]-'a'] = i } for i := 0; i+1 < len(words); i++ { a, b := words[i], words[i+1] n := len(a) if len(b) < n { n = len(b) } j := 0 for ; j < n && a[j] == b[j]; j++ { } if j == n { if len(a) > len(b) { return false } } else if rank[a[j]-'a'] > rank[b[j]-'a'] { return false } } return true}from typing import List
class Solution: def isAlienSorted(self, words: List[str], order: str) -> bool: rank = {c: i for i, c in enumerate(order)} for i in range(len(words) - 1): a, b = words[i], words[i + 1] n = min(len(a), len(b)) j = 0 while j < n and a[j] == b[j]: j += 1 if j == n: if len(a) > len(b): return False elif rank[a[j]] > rank[b[j]]: return False return Truefunction isAlienSorted(words, order) { const rank = new Array(26); const a0 = 'a'.charCodeAt(0); for (let i = 0; i < 26; i++) rank[order.charCodeAt(i) - a0] = i; for (let i = 0; i + 1 < words.length; i++) { const a = words[i], b = words[i + 1]; const n = Math.min(a.length, b.length); let j = 0; while (j < n && a[j] === b[j]) j++; if (j === n) { if (a.length > b.length) return false; } else if (rank[a.charCodeAt(j) - a0] > rank[b.charCodeAt(j) - a0]) { return false; } } return true;}class Solution { public boolean isAlienSorted(String[] words, String order) { int[] rank = new int[26]; for (int i = 0; i < 26; i++) rank[order.charAt(i) - 'a'] = i; for (int i = 0; i + 1 < words.length; i++) { String a = words[i]; String b = words[i + 1]; int n = Math.min(a.length(), b.length()); int j = 0; while (j < n && a.charAt(j) == b.charAt(j)) j++; if (j == n) { if (a.length() > b.length()) return false; } else if (rank[a.charAt(j) - 'a'] > rank[b.charAt(j) - 'a']) { return false; } } return true; }}function isAlienSorted(words: string[], order: string): boolean { const rank: number[] = new Array(26); const a0 = 'a'.charCodeAt(0); for (let i = 0; i < 26; i++) rank[order.charCodeAt(i) - a0] = i; for (let i = 0; i + 1 < words.length; i++) { const a = words[i], b = words[i + 1]; const n = Math.min(a.length, b.length); let j = 0; while (j < n && a[j] === b[j]) j++; if (j === n) { if (a.length > b.length) return false; } else if (rank[a.charCodeAt(j) - a0] > rank[b.charCodeAt(j) - a0]) { return false; } } return true;}Editorial#
The rank-table inversion turns “is character X less than Y in alien order?” into a single int comparison. Edge case: identical prefixes mean the shorter word must come first.
Complexity#
- Time: O(total chars).
- Space: O(1) (26 ranks).
Concept revision#
Related#