剑指 Offer II 114. 外星文字典

192 阅读1分钟

剑指 Offer II 114. 外星文字典

给定一个字符串列表 words ,作为这门语言的词典,words 中的字符串已经 按这门新语言的字母顺序进行了排序 。


var alienOrder = function (words) {
    var c = 0;
    var set = new Set(words.join('').split(''));
    // 收集字母间大小关系
    var larger = new Map(); // w: [e,r,t,f]
    for (var l of set) {
        larger.set(l, new Set());
    }
    while (c < words.length - 1) {
        var pre = words[c];
        var after = words[c + 1];
        for (var i = 0; i < pre.length; i++) {
            if (i >= after.length) return '';
            if (pre[i] !== after[i]) {
                if (larger.get(pre[i]).has(after[i])) return '';
                larger.get(after[i]).add(pre[i]);
                break;
            }
        }
        c += 1;
    }
    var res = [];
    var loop = false; // 是否有环的标记
    var arr = new Array(26).fill(false);
    function f(n, path = new Set()) {
        // f拓扑排序
        if (loop) return;
        if (path.has(n)) {
            loop = true;
            return;
        }
        path.add(n); // 记录当前遍历路径,以监测是否有环。
        var index = n.charCodeAt(0) - 'a'.charCodeAt(0);
        if (!arr[index]) {
            if (larger.get(n).size === 0) {
                // 找到最小的字母,直接压入结果并返回。
                res.push(n);
                arr[index] = true;
                return;
            }
            for (var i of larger.get(n)) {
                f(i, path);
            }
            arr[index] = true;
            res.push(n);
        }
        path.devare(n); // 回溯
    }
    for (var i of set) {
        f(i);
    }
    return loop ? '' : res.join(''); // 有环返回空字符串,无环返回结果。
};