function alienOrder(words) {
  const g = new Graph();
  if (!words || words.length < 2) return words && words.join('');

  for (let i = 1; i < words.length; i++) { // O(n) * O(k)
    const w1 = words[i - 1];
    const w2 = words[i];
    let j = 0;

    while (j < w1.length && j < w2.length && w1[j] === w2[j]) { // O(k), k = max word length
      g.add(w1[j++]);
    }

    if (j === w2.length && w1.length > w2.length) {
      return ''; // shorter words should come first.
    }

    if (w1[j]) g.add(w1[j], w2[j]);
    [...w1.slice(j)].forEach((n) => g.add(n));
    [...w2.slice(j)].forEach((n) => g.add(n));
  }

  // console.log({ g: JSON.stringify(g) });
  // console.log({ g: g.nodes });

  const set = new Set();
  for (const [node] of g.nodes) { // O(?)
    if (hasLoopOrAddToSet(g, node, set)) { // DFS: O(E + V), V: total unique letters
      return '';
    }
  }

  return [...set].join('');
}
Find the order of the alien alphabet given a list of words on lexicographical order.

@param {string[]} words
@return {string} The alien alphabet order.