首页 > 试题广场 >

火车进站

[编程题]火车进站
  • 热度指数:82598 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}火车站一共有 n 辆火车需要入站,每辆火车有一个编号,编号为 1n
\hspace{15pt}同时,也有火车需要出站,由于火车站进出共享一个轨道,所以后入站的火车需要先出站。换句话说,对于某一辆火车,只有在它之后入站的火车都出站了,它才能出站。

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

输入描述:
\hspace{15pt}第一行输入一个整数 n \left(1 \leqq n \leqq 10\right) 代表火车的数量。
\hspace{15pt}第二行输入 n 个整数 a_1,a_2,\dots,a_n \left(1 \leqq a_i \leqq n\right) 代表火车的入站顺序。


输出描述:
\hspace{15pt}输出若干行,每行输出 n 个整数,代表一种出站顺序。你需要按照字典序从小到大依次输出。
示例1

输入

3
1 2 3

输出

1 2 3
1 3 2
2 1 3
2 3 1
3 2 1

说明

\hspace{15pt}在这个样例中,每一种出栈顺序的详细出入站状况为(黑色普通字体代表入站、橙色加粗字体代表出站):
\hspace{23pt}\bullet\,1 \to {\color{orange}{\bf 1}} \to 2 \to {\color{orange}{\bf 2}} \to 3 \to {\color{orange}{\bf 3}}
\hspace{23pt}\bullet\,1 \to {\color{orange}{\bf 1}} \to 2 \to 3 \to {\color{orange}{\bf 3}} \to {\color{orange}{\bf 2}}
\hspace{23pt}\bullet\,1 \to 2 \to {\color{orange}{\bf 2}} \to {\color{orange}{\bf 1}} \to 3 \to {\color{orange}{\bf 3}}
\hspace{23pt}\bullet\,1 \to 2 \to {\color{orange}{\bf 2}} \to 3 \to {\color{orange}{\bf 3}} \to {\color{orange}{\bf 1}}
\hspace{23pt}\bullet\,1 \to 2 \to 3 \to {\color{orange}{\bf 3}} \to {\color{orange}{\bf 2}} \to {\color{orange}{\bf 1}}
import java.util.*;

// 回溯
public class Main {
    private static List<String> res = new ArrayList<>(); // 所有结果
    private static StringBuilder path = new StringBuilder(); // 一次结果

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) nums[i] = in.nextInt();

        backtrack(nums, 0, new Stack<Integer>()); // 调用
        res.sort((s1,s2)->s1.compareTo(s2)); // 排序

        for (String s : res) {
            System.out.println(s);
        }
    }

    // 回溯  (stack、path的恢复比较绕🍓)
    private static void backtrack(int[] nums, int k, Stack<Integer> stack) {
        if (k == nums.length) { // 出口
            res.add(path.toString());
            return;
        }

        stack.push(nums[k]);
        Stack<Integer> stackClone = (Stack<Integer>)stack.clone();  //【 stack、path原件备份
        StringBuilder pathClone = new StringBuilder(path.toString());// 回溯恢复时用到 】
        
        int start = 0;
        if (k == nums.length - 1)
            start = stack.size();// 最后一个了,stack里剩余的全部火车必须出站

        for (int i = start; i <= stack.size(); i++) { // 可以出站[0,size]列火车

            for (int j = 1; j <= i; j++) { // 出j列火车
                path.append(stack.pop() + " ");
            }

            backtrack(nums, k + 1, (Stack<Integer>)stack.clone()); // 下一层 (剩余的火车stack留给下层,注意clone)

            path = new StringBuilder(pathClone.toString()); // 恢复path、stack(必须创建新的)
            stack = (Stack<Integer>)stackClone.clone(); // 不能path=pathCopy,这样不同i会继承上次的残留
        }
    }
}

发表于 2025-03-26 21:55:36 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int a[] = new int[n];//存储火车顺序
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
        }
        List<Integer> everytrain = new ArrayList<>();//存储每次火车方案顺序
        List<List<Integer>> toltrain = new ArrayList<>();//汇总所有方案
        Stack<Integer> b = new Stack<>();//存储火车进出
        train(0, a, b, everytrain, toltrain);

        Collections.sort(toltrain, new Comparator<List<Integer>>() {
            @Override
            public int compare(List<Integer> o1, List<Integer> o2) {
                for (int i = 0; i < o1.size(); i++) {
                    int temp = o1.get(i).compareTo(o2.get(i));
                    if (temp != 0) {
                        return temp;
                    }
                }
                return 0;
            }
        });

        for (List<Integer> p : toltrain) {
            StringBuilder result = new StringBuilder();
            for (int i : p) {
                result.append(i).append(" ");
            }
            System.out.println(result.toString().trim());
        }
    }
    private static void train(int index, int a[], Stack<Integer> c, List<Integer> d,
                              List<List<Integer>> result) {
        if (index == a.length && c.isEmpty()) { //完成某支线
            result.add(new ArrayList<>(d));
            return;
        }
        if (index < a.length) { //进车
            c.push(a[index]);
            train(index + 1, a, c, d, result);
            c.pop();
        }
        if (!c.isEmpty()) { //出车
            int x = c.pop();
            d.add(x);
            train(index, a, c, d, result);
            c.push(x);
            d.remove(d.size() - 1);
        }
    }
}
发表于 2025-03-24 10:40:18 回复(0)
希望我的实现符合大家的思考路线,方便大家看懂
 public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int cnt = in.nextInt();
        int[] trains = new int[cnt];

        for (int i = 0; i < cnt; i++) {
            trains[i] = in.nextInt();
        }

        Stack<Integer> trainInStationSeq = new Stack<>();
        for (int i = cnt - 1; i >= 0; i--) {
            trainInStationSeq.push(trains[i]);
        }
        Stack<Integer> stationStack = new Stack<>();
        ArrayList<String> allSolutions = new ArrayList<>();
        dfs(trainInStationSeq, stationStack, new StringBuilder(), allSolutions);
        Collections.sort(allSolutions);
        for (String s : allSolutions) {
            System.out.println(s);
        }

    }

    /**
     * 深度遍历
     *
     * @param trainInStationSeq
     * @param stationStack
     * @param thisSolution
     * @param allSolutions
     */
    static void dfs(Stack<Integer> trainInStationSeq, Stack<Integer> stationStack, StringBuilder thisSolution, ArrayList<String> allSolutions) {
        List<String> choices = Arrays.asList("pop", "push");
        Stack<Integer> trainInStationSeqOld = (Stack<Integer>) trainInStationSeq.clone();
        Stack<Integer> stationStackOld = (Stack<Integer>) stationStack.clone();
        StringBuilder thisSolutionOld = new StringBuilder(thisSolution);

        // 一条路遍历到底
        if (stationStack.isEmpty() && trainInStationSeq.isEmpty()) {
            allSolutions.add(thisSolution.toString().trim());
            return;
        }
        for (String choice : choices) {
            if (choice.equals("pop") && !stationStack.isEmpty()) {
                Integer pop = stationStack.pop();
                thisSolution.append(pop).append(" ");
                dfs(trainInStationSeq, stationStack, thisSolution, allSolutions);
            }

            if (choice.equals("push") && !trainInStationSeq.isEmpty()) {
                Integer pop = trainInStationSeq.pop();
                stationStack.push(pop);
                dfs(trainInStationSeq, stationStack, thisSolution, allSolutions);
            }
            // 每选择一条路走到底后,需要恢复到之前的状态,再走另外一个分支
            trainInStationSeq = trainInStationSeqOld;
            stationStack = stationStackOld;
            thisSolution = thisSolutionOld;
        }
    }


发表于 2024-09-21 22:00:31 回复(0)
Deque<Integer> stack 模拟出入栈,
List<Integer> curr 存储当前出栈序列
List<List<Integer>> result 存储所有的可能结果
DFS得到最终result
创建int[] order 并对result排序,最后输出
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        int[] seq=new int[n];
        for(int i=0;i<n;i++){
            seq[i]=in.nextInt();
        }
        List<List<Integer>> result=new ArrayList<>();
        List<Integer> curr=new ArrayList<>();
        Deque<Integer> stack=new ArrayDeque<>();
        DFS(result,stack,curr,seq,0);

        int[] order=new int[result.size()];
        for(int i=0;i<order.length;i++){
            order[i]=i;
        }
        quickSort(result,order,0,order.length-1);
        for(int i=0;i<order.length;i++){
            List<Integer> tmp=result.get(order[i]);
            for(int j=0;j<tmp.size()-1;j++){
                System.out.print(tmp.get(j)+" ");
            }
            System.out.print(tmp.get(tmp.size()-1)+"\n");
        }
    }
    private static void quickSort(List<List<Integer>> result,int[] order,int left,int right){
        if(left>=right){
            return;
        }
        Random random=new Random();
        int pivot=left+random.nextInt(right-left+1);
        swap(order,pivot,right);
        int i=left;
        int j=right;
        while(i<=j){
            if(higherRating(result.get(order[i]),result.get(order[right]))){
                i++;
            }else{
                swap(order,i,j);
                j--;
            }
        }
        swap(order,i,right);
        quickSort(result,order,left,i-1);
        quickSort(result,order,i+1,right);
    }

    private static void DFS(List<List<Integer>> result,Deque<Integer> stack,List<Integer> curr,int[] seq,int index){
        //base
        int n=stack.size();  
        if(index==seq.length){
            for(int i=0;i<n;i++){
                curr.add(stack.pollLast());
            }
            result.add(new ArrayList<>(curr));
            for(int i=0;i<n;i++){
                stack.offerLast(curr.remove(curr.size()-1));
            }
            return;
        }   
        for(int i=0;i<=n;i++){    //n+次DFS
            if(i>0){
                curr.add(stack.pollLast());
            }
            stack.offerLast(seq[index]);
            DFS(result,stack,curr,seq,index+1);
            stack.pollLast();
        }
        for(int i=0;i<n;i++){   //还原stack curr
            stack.offerLast(curr.remove(curr.size()-1));
        }
    }

    private static void swap(int[] order,int i,int j){
        if(i==j){
            return;
        }
        int tmp=order[i];
        order[i]=order[j];
        order[j]=tmp;
    }

    private static boolean higherRating(List<Integer> A,List<Integer> B){
        for(int i=0;i<A.size();i++){
            if(A.get(i)<B.get(i)){
                return true;
            }
            if(A.get(i)>B.get(i)){
                return false;
            }
        }
        
        return false;
    }
    
}



发表于 2023-09-09 17:30:50 回复(0)
参照牛客931628554号的代码,对变量名做了一些优化,添加一些注释

import java.util.Scanner;
import java.util.*;


public class Main {
    static List<String> res = new ArrayList<>();   //存放结果,也就是所有可能的出站序列
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            res.clear();
            int n = in.nextInt();//火车的数量
            int[] trains = new int[n];//存放火车编号
            Stack<Integer> station = new Stack<>();//用栈表示车站,只能先进后出
            for (int i = 0; i < n; i++) {
                trains[i] = in.nextInt();
            }
            trainOut(trains, 0, station, "", 0);
            Collections.sort(res); 
            for (String s : res) {
                System.out.println(s);
            }
        }
        in.close();
    }
    public static void trainOut(int[] trains, int in, Stack<Integer> station,
                                String res_temp, int out) {
        if (out == trains.length) {   //out表示已经出站的火车数量。当所有火车出站时,表示一个出站序列完成,将其添加到结果中
            res.add(res_temp);
        }
        if (!station.empty()) {  //当车站还有火车时
            int train = station.pop();  //出站一辆火车
            trainOut(trains, in, station, res_temp + train + " ", out + 1);//该出站火车添加到当前出站序列红,出站火车数量+1
            station.push(train);
        }
        if (in < trains.length) { //当还有火车未进站时
            station.push(trains[in]);//进站一辆火车
            trainOut(trains, in + 1, station, res_temp, out);//已进站火车数量+1
            station.pop();
        }
    }
}

发表于 2023-02-24 15:33:11 回复(2)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
         private static List<Integer> resultList = new ArrayList<>();
    private static Map<Integer,String> resultMap = new HashMap<>();

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        String trim = scanner.nextLine().trim();
        String str = scanner.nextLine().trim();
        String[] split = str.split(" ");

        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            list.add(Integer.valueOf(split[i]));
        }

        Stack<Integer> stack = new Stack<>();
        List<Integer> outStackNumberList = new ArrayList<>();
        Integer remove = list.remove(0);
        stack.push(remove);
        show(list, stack, outStackNumberList);
        Collections.sort(resultList);
        for (Integer key : resultList) {
            System.out.println(resultMap.get(key));
        }
    }

    private static void show(List<Integer> list, Stack<Integer> stack, List<Integer> outStackNumberList) {

        if (list.isEmpty()) {
            // list 为空时说明元素都已经进栈了,后面只剩下出栈然后统计
            while (!stack.isEmpty()) {
                outStackNumberList.add(stack.pop());
            }

            String s = outStackNumberList.toString()
                    .replace("[", "")
                    .replace("]", "")
                    .replaceAll(",", "");
            Integer key = Integer.valueOf(s.replaceAll(" ", ""));
            resultMap.put(key,s);
            resultList.add(key);
        } else {

            if (stack.isEmpty()) {
                stack.push(list.get(0));
                list.remove(0);
                show(list, stack, outStackNumberList);
            } else {
                // 可入,可弹

                // 弹栈
                Integer pop = stack.pop();
                outStackNumberList.add(pop);

                // 将数据拷贝,避免引用传递干扰后续的入栈这个动作
                List<Integer> list2 = new ArrayList<>();
                list2.addAll(list);
                List<Integer> outStackNumberList2 = new ArrayList<>();
                outStackNumberList2.addAll(outStackNumberList);
                Stack<Integer> stack2 = new Stack<>();
                stack2.addAll(stack);
                show(list2, stack2, outStackNumberList2);

                // 回溯
                stack.push(pop);
                outStackNumberList.remove(outStackNumberList.size() - 1);

                // 入栈
                stack.push(list.get(0));
                list.remove(0);
                show(list, stack, outStackNumberList);

            }
        }
    }


}
发表于 2023-02-17 00:36:51 回复(0)
队列和栈的模拟,及递归调用,相对简单
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.Collections;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 获取输入火车数
        int n = in.nextInt();
        // 定义一个队列,表示需要进入的火车
        Queue<String> que = new LinkedList<>();
        // 定义一个栈,模拟火车进出站
        Stack<String> stack = new Stack<>();
        // 定义一个List集合,用于存放火车出栈顺序集合
        List<String> list = new ArrayList<>();
        // 定义一个String,表示出栈顺序
        String pop = "";
        // 将火车进入队列
        for (int i = 0; i < n; i++) {
            que.offer(String.valueOf(in.nextInt()));
        }
        // 模拟火车进出站
        trainEnter(que, stack, list, pop);
        // 对出栈顺序集合进行排序
        Collections.sort(list);
        // 输出结果
        list.forEach(p-> {
            System.out.println(p);
        });
    }

    /**
     * 模拟火车进站或出栈.
     */
    private static void trainEnter(Queue<String> que, Stack<String> stack,
                                   List<String> list, String pop) {
        if (que.isEmpty() && stack.isEmpty()) {
            // 进站队列和栈都为null,则return,将出栈顺序添加到list
            list.add(pop);
            return;
        }
        // 主要车站还存在车,遍出栈
        if (!stack.isEmpty()) {
            // 先克隆,保证数据的原始性质
            Queue<String> tempQueue = new LinkedList<>(que);
            Stack<String> tempStack = (Stack<String>) stack.clone();
            // 栈顶出栈
            String tempOutQueue = pop + (tempStack.pop() + " ");
            // 递归调用,下一个车辆进站
            trainEnter(tempQueue, tempStack, list, tempOutQueue);
        }
        // 主要车队不为空,遍进站
        if (!que.isEmpty()) {
            // 先克隆,保证数据的原始性质
            Queue<String> tempQueue = new LinkedList<>(que);
            Stack<String> tempStack = (Stack<String>) stack.clone();
            // 后车出队列,返回队列第一个元素,并删除
            String train = tempQueue.poll();
            // 后车进站
            tempStack.push(train);
            // 递归调用,下一个车辆进站
            trainEnter(tempQueue, tempStack, list, pop);
        }
    }
}

发表于 2023-02-14 17:50:27 回复(1)
第一次刷牛客,这体验直接想劝退我了,为什么不能够获取正确的结果是多少的....

发表于 2022-10-12 18:25:21 回复(1)
  1. 递归,将出站顺序记为一个数字,对数字进行排序要比字符串排序快得多,如1,2,3记为123,这样可以使用TreeSet来自动排序。
  2. 用数字还有一个好处就是数字是基本数据类型而不是引用数据类型,不需要考虑递归过程中对引用数据类型的改变。
  3. 如果有n辆车,那么最终出站数字序列的量级一定是10^(n - 1),比如3辆车的出站序列123的量级是100,判断递归终止的条件就是当前数字序列达到了量级10^(n - 1).
  4. 最后将TreeSet里的数字序列依次取出来,因为每个数字的量级scale都是相同的,所以对于每个数字序列,可以很方便地从高位到低位取出每个数字进行字符串拼接。
运行时间:66ms
超过100.00% 用Java提交的代码
占用内存:13328KB
超过100.00% 用Java提交的代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[] parts = br.readLine().split(" ");
        int[] identifiers = new int[n];
        for (int i = 0; i < n; i++) {
            identifiers[i] = Integer.parseInt(parts[i]);
        }

        Solution sl = new Solution();
        System.out.println(sl.getProgrammes(identifiers, n));
    }
}

class Solution {

    int num;
    int scale;
    int[] identifiers;

    public StringBuilder getProgrammes(int[] identifiers, int num) {
        this.num = num;
        this.identifiers = identifiers;
        scale = (int) Math.pow(10, num - 1);
        TreeSet<Integer> digitalForm = new TreeSet<>();
        dfs(digitalForm, 0, 0, 0);

        StringBuilder programmes = new StringBuilder();
        for (int digit : digitalForm) {
            int scale = this.scale;
            while (digit != 0) {
                programmes.append(digit / scale).append(" ");
                digit = digit % scale;
                scale /= 10;
            }
            programmes.append("\n");
        }
        return programmes;
    }

    public void dfs(TreeSet<Integer> digitForm, int programme, int station, int cur) {
        //进站
        if (cur < num) {
            int newStation = station * 10 + identifiers[cur];
            dfs(digitForm, programme, newStation, cur + 1);
        }
        //出站
        if (station != 0) {
            programme = programme * 10 + station % 10;
            station /= 10;
            if (programme / scale != 0) {
                digitForm.add(programme);
                return;
            }
            dfs(digitForm, programme, station, cur);
        }
    }
}




发表于 2022-09-05 12:42:26 回复(0)
import java.util.*;

public class Main {

    private static boolean[] used = null;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        used = new boolean[n + 1];

        int[] nums = new int[n];
        int[] tmp = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }

        dfs(n, nums, tmp, 0);

        sc.close();
    }

    private static void dfs(int n, int[] nums, int[] tmp, int step) {
        if (step == nums.length) {
            if (isValid(nums, tmp)) {
                System.out.println(printResult(tmp));
            }
            return;
        }

        for (int i = 1; i <= n; i++) {
            if (used[i]) {
                continue;
            }

            used[i] = true;
            tmp[step] = i;
            dfs(n, nums, tmp, step + 1);
            used[i] = false;
        }
    }

    private static boolean isValid(int[] nums, int[] tmp) {

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i);
        }

        Set<Integer> set = new HashSet<>();
        int idx = 0;
        for (int i = 0; i < tmp.length; i++) {
            while (!set.contains(tmp[i])) {
                set.add(nums[idx]);
                idx++;
            }

            for (int j = map.get(tmp[i]) + 1; j < idx; j++) {
                if (set.contains(nums[j])) {
                    return false;
                }
            }
            set.remove(tmp[i]);
        }
        return true;
    }

    private static String printResult(int[] tmp) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < tmp.length - 1; i++) {
            sb.append(tmp[i]).append(" ");
        }
        sb.append(tmp[tmp.length - 1]);
        return sb.toString();
    }
}

发表于 2022-05-14 22:10:07 回复(0)
简洁Java代码
import java.util.*;

public class Main {
    public static List<String> res = new ArrayList<>();

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int[] nums = new int[n];
            Stack<Integer> stk = new Stack<>();
            for (int i = 0; i < n; i++) {
                nums[i] = in.nextInt();
            }
            helper(nums, 0, stk, "", 0);
            Collections.sort(res);
            for (String s : res) {
                System.out.println(s);
            }
        }
    }

    public static void helper(int[] nums, int i, Stack<Integer> stk, String s, int n) {
        if (n == nums.length)
            res.add(s);
        if (!stk.empty()) {
            int tmp = stk.pop();
            helper(nums, i, stk, s + tmp + " ", n +1);
            stk.push(tmp);
        }
        if (i < nums.length) {
            stk.push(nums[i]);
            helper(nums, i + 1, stk, s, n);
            stk.pop();
        }
    }
}


发表于 2022-04-06 11:12:10 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int cnt = in.nextInt();
            int[] arr = new int[cnt];
            for (int i = 0; i < cnt; i++) {
                arr[i] = in.nextInt();
            }
            pp(arr);
        }
    }
    
    private static void pp(int[] arr) {
        List<Integer> output = new ArrayList<>();
        List<Integer> op = new ArrayList<>();
        Stack<Integer> stack = new Stack<>();
        l = new ArrayList<>();
        dfs(arr, 0, output, stack);
        l.sort(String::compareTo);
        for (String s : l) {
            System.out.println(s);
        }
    }
    
    private static List<String> l = new ArrayList<>();
    
    private static void dfs(int[] arr, int idx, List<Integer> output, Stack<Integer> stack) {
        if (idx == arr.length) {
            print(output, stack);
            return;
        }
        // buffer -> out
        if (!stack.isEmpty()) {
            Integer t = stack.pop();
            output.add(t);
            dfs(arr,idx,output,stack);
            output.remove(t);
            stack.push(t);
        }
        // buffer
        stack.push(arr[idx]);
        dfs(arr, idx + 1, output, stack);
        stack.pop();
    }
    
    private static void print(List<Integer> list, Stack<Integer> stack) {
        StringBuilder sb = new StringBuilder(32);
        for (Integer i : list) {
            sb.append(i).append(' ');
        }
        for (int i = stack.size() -1; i >= 0; i--) {
            sb.append(stack.get(i)).append(' ');
        }
        //System.out.println(sb.toString());
        l.add(sb.toString());
    }
}

发表于 2022-03-21 23:36:08 回复(1)

通过模拟栈的操作来生成所有可能的序列,超级好理解:

import java.util.*;

public class Main {
    // 生成数字的入栈出栈操作序列,使用回溯进行生成
    public void generateStackOperator(int[] nums, int n, int p, int q,
                                      List<List<Integer>> ret, List<Integer> sub) {
        if (q == n) {
            ret.add(new ArrayList<>(sub));
            return;
        }
        if (p < n) {
            sub.add(1);
            p++;
            generateStackOperator(nums, n, p, q, ret, sub);
            sub.remove(sub.size() - 1);
            p--;
        }
        if (p > q) {
            sub.add(0);
            q++;
            generateStackOperator(nums, n, p, q, ret, sub);
            sub.remove(sub.size() - 1);
            q--;
        }
    }

    // 模拟栈的入栈出栈顺序,将出栈结果放入结果集中
    public List<List<Integer>> processStackSeries(int[] nums, List<List<Integer>> operatorSeries) {
        List<List<Integer>> ret = new ArrayList<List<Integer>>();
        Deque<Integer> stack = new LinkedList<Integer>();

        for (List<Integer> series : operatorSeries) {
            int start = 0;
            List<Integer> subRet = new ArrayList<>();
            for (Integer op : series) {
                if (op == 1) {
                    stack.push(nums[start]);
                    start++;
                } else {
                    // op is 0
                    subRet.add(stack.pop());
                }
            }
            ret.add(subRet);
        }

        return ret;
    }

    // 利用一个栈,通过模拟栈的入栈和出栈操作,来获得所有可能的序列
    public static void main(String[] args) {
        Main obj = new Main();

        Scanner sc = new Scanner(System.in);

        while (sc.hasNextInt()) {
            int trainCounts = sc.nextInt();
            int[] trains = new int[trainCounts];
            for (int i = 0; i < trainCounts; i++) {
                trains[i] = sc.nextInt();
            }

            List<List<Integer>> operatorSeries = new ArrayList<List<Integer>>();
            List<Integer> subSeries = new ArrayList<>();
            obj.generateStackOperator(trains, trains.length, 0, 0, operatorSeries, subSeries);

            List<List<Integer>> ret = obj.processStackSeries(trains, operatorSeries);
            Collections.sort(ret, new Comparator<List<Integer>>() {
                @Override
                public int compare(List<Integer> o1, List<Integer> o2) {
                    int length = o1.size();
                    int res = 0;
                    for (int i = 0; i < length; i++) {
                        if (o1.get(i) < o2.get(i)) {
                            res = -1;
                            break;
                        } else if (o1.get(i) == o2.get(i)) {
                            if (i == length - 1) {
                                return 0;
                            } else {
                                continue;
                            }
                        } else {
                            res = 1;
                            break;
                        }
                    }
                    return res;
                }
            });

            for (List<Integer> subRet : ret) {
                for (Integer n : subRet) {
                    System.out.print(n);
                    System.out.print(" ");
                }
                System.out.println();
            }

        }
    }
}
发表于 2022-02-25 14:14:58 回复(0)
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            String[] orders = new String[n];
            for (int i = 0; i < n; i++) {
                orders[i] = sc.next();
            }
            Stack<String> stack = new Stack<>();
            List<String> resList = new ArrayList<>();
            dfs(0, orders, new ArrayList<>(), resList, stack);
            resList.sort(new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    char[] chars1=o1.toCharArray();
                    char[] chars2=o2.toCharArray();
                    int i=0;
                    while(i<chars1.length && i<chars2.length){
                        if(chars1[i]>chars2[i]){
                            return 1;
                        }else if(chars1[i]<chars2[i]){
                            return -1;
                        }else{
                            i++;
                        }
                    }
                    if(i==chars1.length){  //o1到头
                        return -1;
                    }
                    if(i== chars2.length){ //o2到头
                        return 1;
                    }
                    return 0;
                }
            });
            for (String s :
                    resList) {
                System.out.println(s);
            }
        }
    }

    public static void dfs(int index, String[] ops, List<String> record,
                           List<String> res, Stack<String> stack) {
        if (index == ops.length) {
            List<String> temp = new ArrayList<>(record);
            Stack<String> tStack = new Stack<>();
            tStack.addAll(stack);
            while(!tStack.empty()) {
                temp.add(tStack.pop());
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < temp.size() - 1; i++) {
                sb.append(temp.get(i)).append(" ");
            }
            sb.append(temp.get(temp.size() - 1));
            res.add(sb.toString());
        } else {
            if(!stack.isEmpty()) {
                String temp = stack.pop();
                record.add(temp);
                dfs(index, ops, record, res, stack);
                record.remove(record.size() - 1);
                stack.add(temp);
            }
            stack.add(ops[index]);
            dfs(index + 1, ops, record, res, stack);
            stack.pop();
        }

    }
}
发表于 2022-01-09 19:49:34 回复(0)
import java.util.*;
public class Main {
    //存放结果
    public static List<String> list;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()){
            //初始化结果集
            list = new ArrayList<>();
            int n = sc.nextInt();
            //保存站外火车
            int[] arr= new int[n];
            //保存站内火车
            LinkedList<Integer> stack = new LinkedList<>();
            for(int i = 0;i < n;i++){
                arr[i] = sc.nextInt();
            }
            //执行方法
            trainOut(arr,stack,"",0,0);
            Collections.sort(list);
            list.forEach(s->System.out.println(s));
        }
    }
    public static void trainOut(int[] arr,LinkedList<Integer> stack,String result,int in,int out){
        if(out == arr.length){
            list.add(result);
        }
        if(!stack.isEmpty()){
            int tmp = stack.pop();
            trainOut(arr,stack,result + tmp + " ",in,out+1);
            stack.push(tmp);
        }
        if(in < arr.length){
            stack.push(arr[in]);
            trainOut(arr,stack,result,in+1,out);
            stack.pop();
        }
    }
}

发表于 2021-12-05 02:18:17 回复(0)
import java.util.*;

public class Main{

    static List<String> l = new ArrayList<>(); //储存结果

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        while (in.hasNext()) {
            l.clear(); //静态变量,每次先清空
            int nums = in.nextInt();
            int[] id = new int[nums];
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < nums; i++) {
                id[i] = in.nextInt();
            }
            trainOut(id, 0, stack, "", 0);
           //对结果集排序
            Collections.sort(l); 
            for (String str : l) {
                System.out.println(str);
            }
        }
        in.close();
    }

//i为入栈次数,n为出栈次数,str存储一趟结果

    public static void trainOut(int[] id, int i, Stack<Integer> s, String str, int n) {
        if (n == id.length) {
            l.add(str); //如果所有火车均出栈则将当前结果保存
        }

        if (!s.empty()) { //栈非空时出栈
            int temp = s.pop();
            trainOut(id, i, s, str + temp + " ", n + 1);
            s.push(temp); //恢复现场
        }

        if (i < id.length) {
            s.push(id[i]);
            trainOut(id, i + 1, s, str, n);
            s.pop(); //恢复现场

        }
    }
}

发表于 2021-11-07 16:47:40 回复(0)
就是n个数进栈出栈的方式 
发表于 2021-09-27 20:56:08 回复(0)
递归解决万物
import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int n = sc.nextInt();
            int[] arr=new int[n];
            for(int i=0;i<n;i++){
                arr[i]=sc.nextInt();
            }
            Set<String> set=new TreeSet<>();
            solve(arr,0,"",new ArrayList<>(),set);
	    	for(String s:set)
                System.out.println(s.trim());
		}
		sc.close();
	}
    
    private static void solve(int[] arr,int index,String res,List<Integer> list,Set<String> set) {
		if(index==arr.length) {
			for(int i=list.size()-1;i>=0;i--) {
				res=res+" "+list.get(i);
			}
			set.add(res);
			return ;
		}
		while(true) {
			List<Integer> tmp=new ArrayList<>(list);
			tmp.add(arr[index]);
			solve(arr,index+1,res,tmp,set);
			if(list.size()==0)
				break;
			res=res+" "+list.remove(list.size()-1);
		}
	}
}


发表于 2021-03-31 14:14:58 回复(1)

问题信息

难度:
23条回答 39787浏览

热门推荐

通过挑战的用户

查看代码
火车进站