zoukankan      html  css  js  c++  java
  • 华为OJ:火车进站

    给定一个正整数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
    解题
    1.求出所有排列
    2.判断合法出入栈
    如何求排列
    把一个字符串看成两部分组成:第一部分为它的第一个字符,第二部分是后面的所有字符。求整个字符串的排列,分为两步: 
    第一步:求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换 
    第二步:固定第一个字符,求后面所有字符的排列,这个时候把后面的所有字符看成两个部分:后面字符的第一个字符,以及这个字符之后的所有字符,这是一个递归的过程。
    代码如下
        /**
         * 求出所有排列 
         * @param A
         * @param start
         * @param n
         * @param result
         */
        private static void Permutation(int[] A,int start,int n,ArrayList<int[]> result){
            if(start == n){
                return;
            }
            if(start == n-1){
                int[] B = A.clone();
                result.add(B);
                return;
            }
            for(int i=start;i<n;i++){
                swap(A,start,i);
                Permutation(A,start+1,n,result);// 后一个位置开始,进行递归
                swap(A,start,i);
            }
            
        }
        private static void swap(int[] A,int i,int j){
            int t = A[i];
            A[i] = A[j];
            A[j] = t;
        }
    如何判断是合法出栈队列?
    本质就是模拟可能出栈序列
        private static boolean isLegal(int[] in,int[] out,int n){
            LinkedList<Integer> stack = new LinkedList<Integer>();
            int i=0;
            int j=0;
            while(i<n){ // in 还有元素的时候都需要判断 
                if(in[i] == out[j]){ //  相等时候就不用入栈,直接后移 
                    i++;
                    j++;
                }else{
                    if(stack.isEmpty()){ //空stack 就只有入栈了
                        stack.push(in[i]);
                        i++;
                    }else{
                        int top = stack.peek(); // 栈顶元素相等,进行出栈
                        if(top ==out[j]){
                            j++;
                            stack.pop();
                        }else if(i<n){ //  不等时候入栈 
                            stack.push(in[i]);
                            i++;
                        }
                    }
                }
            }
            while(!stack.isEmpty() && j<n){ // in 的结束后,栈中元素进程出栈序列应该和out剩余的元素 相同 
                int top = stack.pop();
                if(top == out[j]){
                    j++;
                }else{
                    return false;
                }
            }
            return true;
            
        }
    
    

    这样就OK了

    注意最后还有一个排序的过程

    但是如果在华为OJ上做,就一个测试样例,不排序也可以,在牛客上就需要排序了

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Scanner;
    import java.util.Set;
    import java.util.TreeSet;
     
    public class Main {
     
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            while(in.hasNext()){
                int n = in.nextInt();
                int[] A = new int[n];
                for(int i=0;i<n;i++){
                    A[i] = in.nextInt();
                }
                int start = 0;
                ArrayList<int[]> result = new ArrayList<int[]>();
                 
                Permutation(A,start,n,result);
                Set<String> sortResult = new TreeSet<String>();
                 
                for(int[] out:result){
                    if(isLegal(A,out,n)){
                        StringBuilder sb = new StringBuilder();
                        for(int i=0;i<n-1;i++){
                            sb.append(out[i]+" ");
                        }
                        sb.append(out[n-1]);
                        sortResult.add(sb.toString());
    //                  System.out.println(sb.toString());
                    }
                }
                for(String list:sortResult){
                    System.out.println(list);
                }
            }
            in.close();
     
        }
        private static boolean isLegal(int[] in,int[] out,int n){
            LinkedList<Integer> stack = new LinkedList<Integer>();
            int i=0;
            int j=0;
            while(i<n){ // in 还有元素的时候都需要判断
                if(in[i] == out[j]){ //  相等时候就不用入栈,直接后移
                    i++;
                    j++;
                }else{
                    if(stack.isEmpty()){ //空stack 就只有入栈了
                        stack.push(in[i]);
                        i++;
                    }else{
                        int top = stack.peek(); // 栈顶元素相等,进行出栈
                        if(top ==out[j]){
                            j++;
                            stack.pop();
                        }else if(i<n){ //  不等时候入栈
                            stack.push(in[i]);
                            i++;
                        }
                    }
                }
            }
            while(!stack.isEmpty() && j<n){ // in 的结束后,栈中元素进程出栈序列应该和out剩余的元素 相同
                int top = stack.pop();
                if(top == out[j]){
                    j++;
                }else{
                    return false;
                }
            }
            return true;
             
        }
        /**
         * 求出所有排列
         * @param A
         * @param start
         * @param n
         * @param result
         */
        private static void Permutation(int[] A,int start,int n,ArrayList<int[]> result){
            if(start == n){
                return;
            }
            if(start == n-1){
                int[] B = A.clone();
                result.add(B);
                return;
            }
            for(int i=start;i<n;i++){
                swap(A,start,i);
                Permutation(A,start+1,n,result);
                swap(A,start,i);
            }
             
        }
        private static void swap(int[] A,int i,int j){
            int t = A[i];
            A[i] = A[j];
            A[j] = t;
        }
     
    }


  • 相关阅读:
    C#基础篇十小练习
    C#基础篇九OOP属性结构枚举
    C#基础篇八构造函数和面向对象思想
    C#基础篇七类和静态成员
    C#基础篇六飞行棋
    C#基础篇五值类型和引用类型
    数据与地址的自动给定---基于状态机
    SPI 核的寄存器空间
    mig_7series DDR控制器的配置
    关于zynq7 中MIO的理解
  • 原文地址:https://www.cnblogs.com/theskulls/p/5766612.html
Copyright © 2011-2022 走看看