【中等】算法nodeJs:火车进站

161 阅读2分钟

描述

火车站一共有 n 辆火车需要入站,每辆火车有一个编号,编号为 1 到 n。
同时,也有火车需要出站,由于火车站进出共享一个轨道,所以后入站的火车需要先出站。换句话说,对于某一辆火车,只有在它之后入站的火车都出站了,它才能出站。

现在,已经知道了火车的入站顺序,你需要计算,一共有多少种不同的出站顺序。按照字典序从小到大依次输出全部的出站顺序。

输入描述:

第一行输入一个整数 n(1≦n≦10) 代表火车的数量。
第二行输入 n 个整数 a1​,a2​,…,an​(1≦ai​≦n) 代表火车的入站顺序。

输出描述:

输出若干行,每行输出 n 个整数,代表一种出站顺序。你需要按照字典序从小到大依次输出。

image.png

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    // Write your code here
    const n = Number(await readline());
    const trains = (await readline()).split(" ");
    const result = []; // 保存所有可能的出站顺序
    const stack = []; // 模拟栈
    const sequence = []; // 当前的出站顺序

    // 递归函数
    function dfs(index) {
        // 如果所有火车都处理完毕,将当前出站顺序保存到结果中
        if (index === n && stack.length === 0) {
            result.push([...sequence]);
            return;
        }

        // 选择将当前火车进栈
        if (index < n) {
            stack.push(trains[index]); // 进栈
            dfs(index + 1); // 递归处理下一个火车
            stack.pop(); // 回溯,恢复栈的状态
        }

        // 选择将栈顶的火车出栈
        if (stack.length > 0) {
            const top = stack.pop(); // 出栈
            sequence.push(top); // 记录出站顺序
            dfs(index); // 继续处理当前火车
            sequence.pop(); // 回溯,恢复出站顺序
            stack.push(top); // 恢复栈的状态
        }
    }

    // 从第一个火车开始递归
    dfs(0);

    // 按照字典序排序
    result.sort((a, b) => {
        for (let i = 0; i < a.length; i++) {
            if (a[i] !== b[i]) return a[i] - b[i];
        }
        return 0;
    });

    // 输出结果
    for (const seq of result) {
        console.log(seq.join(" "));
    }
})();