【华为OJ】【072-火车进站】

【华为OJ】【算法总篇章】


【华为OJ】【072-火车进站】

【工程下载】


题目描述

给定一个正整数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.*;

/**
 * Author: 王俊超
 * Date: 2016-01-04 16:41
 * 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);
    }
}
时间: 2024-10-21 14:30:58

【华为OJ】【072-火车进站】的相关文章

华为机试题 火车进站

描述:给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列 输入: 有多组测试用例,每一组第一行输入一个正整数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 思路:先对输入序列进行字

华为OJ—火车进站(栈,字典排序)

给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号.其实也就是输出所有可能的出栈序列. 样例输入: 3 1 2 3 样例输出: 1 2 31 3 22 1 32 3 13 2 1 解答: 其实核心就是一个栈,对于第K个数,在第K个数进栈之前,前面的 K-1 个数要么全部出去了,要么都在栈里面,要么部分在栈里面部分出去了.那么可以假想,在第K个数入栈之前,依次从栈里面出去 0个.1个.2个--栈.si

全排列——火车进站问题(华为OJ)

今天发现一个非常好用的函数next_permutation(),利用这个函数这以很容易的列出一组数据的所有排列组合. 利用全部排列解决了火车进站问题,下面是题目和源码: 题目:给定一个正整数N代表火车数量,0 #include<vector> #include<stack> #include<string> #include<iostream> #include<algorithm> using namespace std; //////////

[华为机试练习题]13.火车进站

题目 描述: 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 题目类别: 栈 难度: 高级 运行时间限制: 10Sec 内存限制: 128MByte 阶段: 入职前练习 输入: 有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample. 样例

【华为OJ】201301 JAVA 题目0-1级 将数组分为相等的两组

描述:  编写一个函数,传入一个int型数组,返回该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),能满足以上条件,返回true:不满足时返回false. 知识点: 语言基础,字符串,循环,函数,指针,枚举,位运算,结构体,联合体,文件操作,递归    题目来源: 内部整理  练习阶段: 初级  运行时间限制: 10Sec 内存限制: 128MByte 输入: 输入输入的数据个数 输入一个int型数组 输出: 返

华为OJ:汽水瓶

题目有点像小学数学题,因为三个空瓶可以换一瓶汽水,但喝完一瓶汽水就可以得到一个空瓶.所以相当于两个空瓶就可以换到一瓶汽水. 把输入除以2即可.这里讲一下java多出入,可以用in.hasNext(),就相当于C/C++里面的while(scanf("%d",n)!=EOF). import java.util.Scanner; public class qishuiping { public static void main(String args[]){ Scanner input=

华为OJ:分段排序

题目有点绕,一个是要二分,用三个字符串,存前,中,后三个,前,后部分都降序排序,然后后半部分再反转一下,讲三部分合起来就好了. import java.util.Scanner; public class dividesort { public static void sort(StringBuffer s){ for(int i=0;i<s.length();i++){ for(int j=i;j<s.length();j++){ if(s.charAt(i)>s.charAt(j))

华为OJ:2290 字符串最后一个单词的长度

用JAVA就很简单,只要用spilt函数,再输出最后一个字符串. 题意是要求你先自己写分隔好字符串这样子.有个比较坑的地方就是测试用例应该有个全为空的,要注意. import java.util.Scanner; public class Main { public static void main(String args[]){ Scanner input=new Scanner(System.in); String s=input.nextLine(); String ss[]=s.spli

华为OJ: 公共字串计算

有几个需要注意的地方,一个这道题是不区分大小写的,所以在计算之前对输入的字符串要做小写或者大写的转换. 第二个,思路一定要清晰,先将s1从[i]处开始与s2的[j]开始匹配,不相等则j++直到j等于s2.length()-1,相等,则i++,j++.注意,这里就是i++,即下次重新开始从s[i]开始匹配时,两次i之间的距离可能会超过1.再j那里设置一个计数器计数即可. import java.util.Scanner; public class findMaxSubStringLength {