题解 | #火车进站#

火车进站

http://www.nowcoder.com/practice/97ba57c35e9f4749826dc3befaeae109

import java.util.*;

// 思路:主要思想是递归,之所以产生很多方案的原因就是,每次进来一辆火车后,我们将其压入栈中,然后我们可以有两种选择,一是不弹出,二是弹出;
// 对于第二种弹出元素,弹出的个数的范围取决于当前栈中元素的个数,所以遍历每种情况,在遍历每种情况的时候再递归到下一辆火车
public class Main {
    static Deque<Integer> stack;
    static int[] nums, outNums;
    static int n;
    static List<String> res;
    public static void main(String[] args) {
        // 完成输入
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        nums = new int[n];
        for (int i=0; i<n; i++) nums[i] = in.nextInt();
        // outNums是用来记录当前递归中,已经出站的火车编号; stack是记录当前车站中还有哪些火车; 
        // res是记录所有结果并进行排序,因为题目要求所有方案以字典序排序输出,所以没办法必须加
        outNums = new int[n];
        stack = new LinkedList<>();
        res = new ArrayList<>();
        // 开始遍历
        dfs(0, 0);
        // 对所有方案排序,并输出
        Collections.sort(res);
        for (String str:res) System.out.println(str);
    }
    
    // i代表已经递归到了第i辆火车,cnt代表已经已经出站的火车数量,即是outNums的下标
    public static void dfs(int i, int cnt) {
        // 这个tmp栈很重要,这是保证dfs返回时,stack中的元素和进来时一样
        Deque<Integer> tmp = new LinkedList<>();
        // 压入当前火车
        stack.push(nums[i]);
        
        // 当递归到最后一辆火车时,我们只需要将其压入栈中,这时所能做的只有弹出栈中所有元素,并将其添加到outNums数组中
        if (i==n-1) {
            
            // 弹出栈中所有元素
            while (stack.size() > 0) {
                tmp.push(stack.peek());
                outNums[cnt++] = stack.pop();
            }
            // 这里>1是因为stack中本身不含有nums[i]
            while (tmp.size() > 1) stack.push(tmp.pop());
            // 将当前方案以字符串形式保存到res中
            StringBuilder sb = new StringBuilder();
            for (int outNum:outNums) sb.append(outNum).append(" ");
            res.add(sb.toString());
        }
        // 如果没有递归到最后一辆火车,那么在将当前火车编号压入栈后,有很多选择,这也就产生了很多方案
        // 一种就是继续压;还有一种就是开始弹出元素,弹出元素个数范围是[0, size](包含两边界),那么就需要依次遍历
        else {
            int size = stack.size();
            // 继续压
            dfs(i+1, cnt);
            // 开始弹出元素
            for (int j=0; j<size; j++) {
                tmp.push(stack.peek());
                outNums[cnt++] = stack.pop();
                dfs(i+1, cnt);
            }
            // 这里>1是因为stack中本身不含有nums[i],
            while (tmp.size() > 1) stack.push(tmp.pop());
        }
    }
}
全部评论
while (tmp.size() > 1) 临时栈这个有点没看懂?为什么不把临时栈中所有弹出来?而是要留一个。
点赞 回复 分享
发布于 2022-08-08 16:28
直接搞晕了
点赞 回复 分享
发布于 2022-10-05 23:26 上海

相关推荐

10-25 02:13
门头沟学院 C++
牛客7351937293号:8.27笔试10.22评估
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
25 9 评论
分享
牛客网
牛客企业服务