string alienOrder(vector<string>& words) {
map<char, set<char>> adj;
for (auto& w : words) for (char ch : w) if (!adj.count(ch)) adj[ch] = {};
for (size_t i = 0; i < words.size(); i++) {
for (size_t j = i + 1; j < words.size(); j++) {
string a = words[i], b = words[j];
size_t k = 0;
while (k < a.size() && k < b.size() && a[k] == b[k]) k++;
if (k < a.size() && k < b.size()) adj[a[k]].insert(b[k]);
else if (a.size() > b.size()) return "";
}
}
set<char> remaining; for (auto& kv : adj) remaining.insert(kv.first);
string result;
while (!remaining.empty()) {
char pick = 0; bool found = false;
for (char ch : remaining) {
bool blocked = false;
for (char other : remaining) if (adj[other].count(ch)) blocked = true;
if (!blocked) {
pick = ch; found = true;
break;
}
}
if (!found) return "";
result += pick;
remaining.erase(pick);
}
return result;
}
public String alienOrder(String[] words) {
Map<Character, Set<Character>> adj = new LinkedHashMap<>();
for (String w : words) for (char ch : w.toCharArray()) adj.putIfAbsent(ch, new LinkedHashSet<>());
for (int i = 0; i < words.length; i++) {
for (int j = i + 1; j < words.length; j++) {
String a = words[i], b = words[j];
int k = 0;
while (k < a.length() && k < b.length() && a.charAt(k) == b.charAt(k)) k++;
if (k < a.length() && k < b.length()) adj.get(a.charAt(k)).add(b.charAt(k));
else if (a.length() > b.length()) return "";
}
}
Set<Character> remaining = new LinkedHashSet<>(adj.keySet());
StringBuilder result = new StringBuilder();
while (!remaining.isEmpty()) {
Character pick = null;
for (char ch : remaining) {
boolean blocked = false;
for (char other : remaining) if (adj.get(other).contains(ch)) blocked = true;
if (!blocked) {
pick = ch;
break;
}
}
if (pick == null) return "";
result.append(pick);
remaining.remove(pick);
}
return result.toString();
}
def alien_order(words):
adj = {}
for w in words:
for ch in w: adj.setdefault(ch, set())
for i in range(len(words)):
for j in range(i + 1, len(words)):
a, b = words[i], words[j]
k = 0
while k < len(a) and k < len(b) and a[k] == b[k]: k += 1
if k < len(a) and k < len(b): adj[a[k]].add(b[k])
elif len(a) > len(b): return ''
remaining = list(adj)
result = ''
while remaining:
pick = None
for ch in remaining:
blocked = False
for other in remaining:
if ch in adj[other]: blocked = True
if not blocked:
pick = ch
break
if pick is None: return ''
result += pick
remaining.remove(pick)
return result
function alienOrder(words: string[]): string {
const adj = new Map<string, Set<string>>();
for (const w of words) for (const ch of w) if (!adj.has(ch)) adj.set(ch, new Set());
for (let i = 0; i < words.length; i++) {
for (let j = i + 1; j < words.length; j++) {
const a = words[i], b = words[j];
let k = 0;
while (k < a.length && k < b.length && a[k] === b[k]) k++;
if (k < a.length && k < b.length) adj.get(a[k])!.add(b[k]);
else if (a.length > b.length) return '';
}
}
const remaining = new Set(adj.keys());
let result = '';
while (remaining.size > 0) {
let pick: string | null = null;
for (const ch of remaining) {
let blocked = false;
for (const other of remaining) if (adj.get(other)!.has(ch)) blocked = true;
if (!blocked) {
pick = ch;
break;
}
}
if (pick === null) return '';
result += pick;
remaining.delete(pick);
}
return result;
}
string alienOrder(vector<string>& words) {
map<char, set<char>> adj;
map<char, int> indegree;
for (auto& w : words) {
for (char ch : w) {
if (!adj.count(ch)) {
adj[ch] = {};
indegree[ch] = 0;
}
}
}
for (size_t i = 0; i + 1 < words.size(); i++) {
string a = words[i], b = words[i + 1];
if (a.size() > b.size() && a.compare(0, b.size(), b) == 0) return "";
for (size_t k = 0; k < min(a.size(), b.size()); k++) {
if (a[k] != b[k]) {
if (!adj[a[k]].count(b[k])) {
adj[a[k]].insert(b[k]);
indegree[b[k]]++;
}
break;
}
}
}
vector<char> queue;
for (auto& [ch, d] : indegree) if (d == 0) queue.push_back(ch);
string result;
size_t head = 0;
while (head < queue.size()) {
char ch = queue[head++];
result += ch;
for (char next : adj[ch]) {
indegree[next]--;
if (indegree[next] == 0) queue.push_back(next);
}
}
return result.size() == adj.size() ? result : "";
}
public String alienOrder(String[] words) {
Map<Character, Set<Character>> adj = new LinkedHashMap<>();
Map<Character, Integer> indegree = new LinkedHashMap<>();
for (String w : words) {
for (char ch : w.toCharArray()) {
if (!adj.containsKey(ch)) {
adj.put(ch, new LinkedHashSet<>());
indegree.put(ch, 0);
}
}
}
for (int i = 0; i + 1 < words.length; i++) {
String a = words[i], b = words[i + 1];
if (a.length() > b.length() && a.startsWith(b)) return "";
for (int k = 0; k < Math.min(a.length(), b.length()); k++) {
if (a.charAt(k) != b.charAt(k)) {
if (!adj.get(a.charAt(k)).contains(b.charAt(k))) {
adj.get(a.charAt(k)).add(b.charAt(k));
indegree.put(b.charAt(k), indegree.get(b.charAt(k)) + 1);
}
break;
}
}
}
List<Character> queue = new ArrayList<>();
for (Map.Entry<Character, Integer> e : indegree.entrySet()) if (e.getValue() == 0) queue.add(e.getKey());
StringBuilder result = new StringBuilder();
int head = 0;
while (head < queue.size()) {
char ch = queue.get(head++);
result.append(ch);
for (char next : adj.get(ch)) {
indegree.put(next, indegree.get(next) - 1);
if (indegree.get(next) == 0) queue.add(next);
}
}
return result.length() == adj.size() ? result.toString() : "";
}
def alien_order(words):
adj = {}
indegree = {}
for w in words:
for ch in w:
if ch not in adj:
adj[ch] = set()
indegree[ch] = 0
for i in range(len(words) - 1):
a, b = words[i], words[i + 1]
if len(a) > len(b) and a.startswith(b): return ''
for k in range(min(len(a), len(b))):
if a[k] != b[k]:
if b[k] not in adj[a[k]]:
adj[a[k]].add(b[k])
indegree[b[k]] += 1
break
queue = [ch for ch, d in indegree.items() if d == 0]
result = ''
head = 0
while head < len(queue):
ch = queue[head]
head += 1
result += ch
for nxt in adj[ch]:
indegree[nxt] -= 1
if indegree[nxt] == 0: queue.append(nxt)
return result if len(result) == len(adj) else ''
function alienOrder(words: string[]): string {
const adj = new Map<string, Set<string>>();
const indegree = new Map<string, number>();
for (const w of words) {
for (const ch of w) {
if (!adj.has(ch)) {
adj.set(ch, new Set());
indegree.set(ch, 0);
}
}
}
for (let i = 0; i + 1 < words.length; i++) {
const a = words[i], b = words[i + 1];
if (a.length > b.length && a.startsWith(b)) return '';
for (let k = 0; k < Math.min(a.length, b.length); k++) {
if (a[k] !== b[k]) {
if (!adj.get(a[k])!.has(b[k])) {
adj.get(a[k])!.add(b[k]);
indegree.set(b[k], indegree.get(b[k])! + 1);
}
break;
}
}
}
const queue: string[] = [];
for (const [ch, d] of indegree) if (d === 0) queue.push(ch);
let result = '';
let head = 0;
while (head < queue.length) {
const ch = queue[head++];
result += ch;
for (const next of adj.get(ch)!) {
indegree.set(next, indegree.get(next)! - 1);
if (indegree.get(next) === 0) queue.push(next);
}
}
return result.length === adj.size ? result : '';
}
string alienOrder(vector<string>& words) {
map<char, set<char>> adj;
for (auto& w : words) for (char ch : w) if (!adj.count(ch)) adj[ch] = {};
for (size_t i = 0; i + 1 < words.size(); i++) {
string a = words[i], b = words[i + 1];
if (a.size() > b.size() && a.compare(0, b.size(), b) == 0) return "";
for (size_t k = 0; k < min(a.size(), b.size()); k++) {
if (a[k] != b[k]) {
adj[a[k]].insert(b[k]);
break;
}
}
}
map<char, int> state;
string out;
function<bool(char)> visit = [&](char ch) -> bool {
int s = state[ch];
if (s == 1) return false;
if (s == 2) return true;
state[ch] = 1;
for (char next : adj[ch]) {
if (!visit(next)) return false;
}
state[ch] = 2;
out += ch;
return true;
};
for (auto& kv : adj) {
if (!visit(kv.first)) return "";
}
return string(out.rbegin(), out.rend());
}
public String alienOrder(String[] words) {
Map<Character, Set<Character>> adj = new LinkedHashMap<>();
for (String w : words) for (char ch : w.toCharArray()) adj.putIfAbsent(ch, new LinkedHashSet<>());
for (int i = 0; i + 1 < words.length; i++) {
String a = words[i], b = words[i + 1];
if (a.length() > b.length() && a.startsWith(b)) return "";
for (int k = 0; k < Math.min(a.length(), b.length()); k++) {
if (a.charAt(k) != b.charAt(k)) {
adj.get(a.charAt(k)).add(b.charAt(k));
break;
}
}
}
Map<Character, Integer> state = new HashMap<>();
StringBuilder out = new StringBuilder();
for (char ch : adj.keySet()) {
if (!visit(adj, state, out, ch)) return "";
}
return out.reverse().toString();
}
private boolean visit(Map<Character, Set<Character>> adj, Map<Character, Integer> state, StringBuilder out, char ch) {
int s = state.getOrDefault(ch, 0);
if (s == 1) return false;
if (s == 2) return true;
state.put(ch, 1);
for (char next : adj.get(ch)) {
if (!visit(adj, state, out, next)) return false;
}
state.put(ch, 2);
out.append(ch);
return true;
}
def alien_order(words):
adj = {}
for w in words:
for ch in w: adj.setdefault(ch, set())
for i in range(len(words) - 1):
a, b = words[i], words[i + 1]
if len(a) > len(b) and a.startswith(b): return ''
for k in range(min(len(a), len(b))):
if a[k] != b[k]:
adj[a[k]].add(b[k])
break
state = {}
out = []
def visit(ch):
s = state.get(ch, 0)
if s == 1: return False
if s == 2: return True
state[ch] = 1
for nxt in adj[ch]:
if not visit(nxt): return False
state[ch] = 2
out.append(ch)
return True
for ch in list(adj):
if not visit(ch): return ''
return ''.join(reversed(out))
function alienOrder(words: string[]): string {
const adj = new Map<string, Set<string>>();
for (const w of words) for (const ch of w) if (!adj.has(ch)) adj.set(ch, new Set());
for (let i = 0; i + 1 < words.length; i++) {
const a = words[i], b = words[i + 1];
if (a.length > b.length && a.startsWith(b)) return '';
for (let k = 0; k < Math.min(a.length, b.length); k++) {
if (a[k] !== b[k]) {
adj.get(a[k])!.add(b[k]);
break;
}
}
}
const state = new Map<string, number>();
const out: string[] = [];
const visit = (ch: string): boolean => {
const s = state.get(ch) ?? 0;
if (s === 1) return false;
if (s === 2) return true;
state.set(ch, 1);
for (const next of adj.get(ch)!) {
if (!visit(next)) return false;
}
state.set(ch, 2);
out.push(ch);
return true;
};
for (const ch of adj.keys()) {
if (!visit(ch)) return '';
}
return out.reverse().join('');
}
string alienOrder(vector<string>& words) {
vector<bool> present(26, false);
for (auto& w : words) for (char ch : w) present[ch - 'a'] = true;
int out[26] = {0};
int indegree[26] = {0};
for (size_t i = 0; i + 1 < words.size(); i++) {
string a = words[i], b = words[i + 1];
size_t len = min(a.size(), b.size());
size_t k = 0;
while (k < len && a[k] == b[k]) k++;
if (k == len) {
if (a.size() > b.size()) return "";
continue;
}
int x = a[k] - 'a', y = b[k] - 'a';
if (!(out[x] & (1 << y))) {
out[x] |= 1 << y;
indegree[y]++;
}
}
vector<int> queue;
int total = 0;
for (int c = 0; c < 26; c++) {
if (!present[c]) continue;
total++;
if (indegree[c] == 0) queue.push_back(c);
}
string result;
for (size_t head = 0; head < queue.size(); head++) {
int x = queue[head];
result += char('a' + x);
for (int y = 0; y < 26; y++) {
if ((out[x] & (1 << y)) && --indegree[y] == 0) queue.push_back(y);
}
}
return (int)result.size() == total ? result : "";
}
public String alienOrder(String[] words) {
boolean[] present = new boolean[26];
for (String w : words) for (char ch : w.toCharArray()) present[ch - 'a'] = true;
int[] out = new int[26];
int[] indegree = new int[26];
for (int i = 0; i + 1 < words.length; i++) {
String a = words[i], b = words[i + 1];
int len = Math.min(a.length(), b.length());
int k = 0;
while (k < len && a.charAt(k) == b.charAt(k)) k++;
if (k == len) {
if (a.length() > b.length()) return "";
continue;
}
int x = a.charAt(k) - 'a', y = b.charAt(k) - 'a';
if ((out[x] & (1 << y)) == 0) {
out[x] |= 1 << y;
indegree[y]++;
}
}
List<Integer> queue = new ArrayList<>();
int total = 0;
for (int c = 0; c < 26; c++) {
if (!present[c]) continue;
total++;
if (indegree[c] == 0) queue.add(c);
}
StringBuilder result = new StringBuilder();
for (int head = 0; head < queue.size(); head++) {
int x = queue.get(head);
result.append((char) ('a' + x));
for (int y = 0; y < 26; y++) {
if ((out[x] & (1 << y)) != 0 && --indegree[y] == 0) queue.add(y);
}
}
return result.length() == total ? result.toString() : "";
}
def alien_order(words):
present = [False] * 26
for w in words:
for ch in w: present[ord(ch) - 97] = True
out = [0] * 26
indegree = [0] * 26
for i in range(len(words) - 1):
a, b = words[i], words[i + 1]
n = min(len(a), len(b))
k = 0
while k < n and a[k] == b[k]: k += 1
if k == n:
if len(a) > len(b): return ''
continue
x, y = ord(a[k]) - 97, ord(b[k]) - 97
if not out[x] & (1 << y):
out[x] |= 1 << y
indegree[y] += 1
queue = []
total = 0
for c in range(26):
if not present[c]: continue
total += 1
if indegree[c] == 0: queue.append(c)
result = ''
head = 0
while head < len(queue):
x = queue[head]
head += 1
result += chr(97 + x)
for y in range(26):
if out[x] & (1 << y):
indegree[y] -= 1
if indegree[y] == 0: queue.append(y)
return result if len(result) == total else ''
function alienOrder(words: string[]): string {
const present = new Array<boolean>(26).fill(false);
for (const w of words) for (let i = 0; i < w.length; i++) present[w.charCodeAt(i) - 97] = true;
const out = new Int32Array(26);
const indegree = new Int32Array(26);
for (let i = 0; i + 1 < words.length; i++) {
const a = words[i], b = words[i + 1];
const len = Math.min(a.length, b.length);
let k = 0;
while (k < len && a[k] === b[k]) k++;
if (k === len) {
if (a.length > b.length) return '';
continue;
}
const x = a.charCodeAt(k) - 97, y = b.charCodeAt(k) - 97;
if (!(out[x] & (1 << y))) {
out[x] |= 1 << y;
indegree[y]++;
}
}
const queue: number[] = [];
let total = 0;
for (let c = 0; c < 26; c++) {
if (!present[c]) continue;
total++;
if (indegree[c] === 0) queue.push(c);
}
let result = '';
for (let head = 0; head < queue.length; head++) {
const x = queue[head];
result += String.fromCharCode(97 + x);
for (let y = 0; y < 26; y++) {
if ((out[x] & (1 << y)) && --indegree[y] === 0) queue.push(y);
}
}
return result.length === total ? result : '';
}