火車進站

題目描述

給定一個正整數N表明火車數量,0<N<10,接下來輸入火車入站的序列,一共N輛火車,
每輛火車以數字1-9編號。要求以字典序排序輸出火車出站的序列號

思路:
    此處所謂字典序排序的意思是這n輛火車有多少種出站的可能順序(也就是數據結構中的棧有多少種出棧順序)。
思路爲用三個變量分別存儲待進站火車,站中火車和已出站火車,其中待進站火車用Queue(隊列)存儲和站中
火車採用stack(棧)存儲,已出站火車採用StringBuilder來存儲,具體實現是採用遞歸的方法,遞歸函數
的參數爲當前待進站火車、站中火車、已出站火車的值所組成的三元組,遞歸結束條件是,未進站火車和站中火
車均爲空,此時輸出已出站火車即爲全部出站的一種可能,遞推關係爲對於當前狀況有讓下一輛火車進站或讓站
中的一輛火車出站兩種可能,對於兩種可能分別調用遞歸函數,便可得出問題的解。

輸入描述

有多組測試用例,每一組第一行輸入一個正整數N(0<N<10),第二行包括N個正整數,範圍爲1到9。

輸出描述

輸出以字典序排序的火車出站序列號,每一個編號以空格隔開,每一個輸出序列換行,具體見sample。

輸入例子

3
1 2 3

輸出例子

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

算法實現

import java.util.*;

/**
 * All Rights Reserved !!!
 */
public class Main {
    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
        Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            String[] ss = new String[n];
            for (int i = 0; i < n; i++) {
                ss[i] = scanner.next();
            }

            System.out.println(trainOut(ss));
        }

        scanner.close();
    }

    /**
     * 此處所謂字典序排序的意思是這n輛火車有多少種出站的可能順序(也就是數據結構中的棧有多少種出棧順序)。
     * 思路爲用三個變量分別存儲待進站火車,站中火車和已出站火車,其中待進站火車用Queue(隊列)存儲和站中
     * 火車採用stack(棧)存儲,已出站火車採用StringBuilder來存儲,具體實現是採用遞歸的方法,遞歸函數
     * 的參數爲當前待進站火車、站中火車、已出站火車的值所組成的三元組,遞歸結束條件是,未進站火車和站中火
     * 車均爲空,此時輸出已出站火車即爲全部出站的一種可能,遞推關係爲對於當前狀況有讓下一輛火車進站或讓站
     * 中的一輛火車出站兩種可能,對於兩種可能分別調用遞歸函數,便可得出問題的解。
     *
     * @param ss
     * @return
     */
    private static String trainOut(String[] ss) {

//        Arrays.sort(ss);

        List<List<String>> result = new ArrayList<>();
        List<String> out = new ArrayList<>(ss.length);
        List<String> unout = new ArrayList<>(ss.length);
        trainOut(0, ss, out, unout, result);

        Collections.sort(result, new Comparator<List<String>>() {

            @Override
            public int compare(List<String> a, List<String> b) {

                int min = a.size() < b.size() ? a.size() : b.size();


                for (int i = 0; i < min; i++) {
                    String as = a.get(i);
                    String bs = b.get(i);
                    if (as.compareTo(bs) != 0) {
                        return as.compareTo(bs);
                    }
                }
                return a.size() - b.size();
            }
        });

        StringBuilder builder = new StringBuilder(256);
        for (List<String> list : result) {
            StringBuilder b = new StringBuilder(64);
            for (String s : list) {
                b.append(s).append(' ');
            }
            b.setCharAt(b.length() - 1, '\n');

            builder.append(b);
        }

        return builder.toString();
    }

    /**
     * 火車進站
     *
     * @param i      火車編號
     * @param ss     全部的火車
     * @param out    火車已經出站的序列
     * @param unout  火車還未出站的序列
     * @param result 保存全部可能的結果
     */
    private static void trainOut(int i, String[] ss, List<String> out, List<String> unout, List<List<String>> result) {

        // 全部的火車已經進站
        if (i >= ss.length) {
            List<String> list = new ArrayList<>();
            for (String s : out) {
                list.add(s);
            }

            // 先進後出
            for (int j = unout.size() - 1; j >= 0; j--) {
                list.add(unout.get(j));
            }

            result.add(list);

            return;
        }

        // 第i輛車進來就出去了
        out.add(ss[i]);
        trainOut(i + 1, ss, out, unout, result);
        // 還原
        out.remove(out.size() - 1);

        // 第i輛車進來沒有出去
        unout.add(ss[i]);
        trainOut(i + 1, ss, out, unout, result);
        // 還原
        unout.remove(unout.size() - 1);
    }
}
相關文章
相關標籤/搜索