【牛客網OJ題】火車進站

問題描述:

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

輸入描述:

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

輸出描述:

輸出以字典序從小到大排序的火車出站序列號,每個編號以空格替換,每個輸出序列換行,具體見sample。

示例1

輸入

3
1 2 3

輸出

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

 分析:

思路爲用三個變量分別存儲:
待進站火車
站中火車(用Stack存儲)
已出站火車
 
具體實現思路:
 
第一種:
採用遞歸的方法,遞歸函數的參數爲當前待進站火車、站中火車、已出站火車的值所組成的三元組,遞歸結束條件 是,未進站火車和站中火車均爲空,此時輸出已出站火車即爲所有出站的一種可能,遞推關係爲對於當前情況有讓下 一輛火車進站或讓站中的一輛火車出站兩種可能,對於兩種可能分別調用遞歸函數,即可得出問題的解。
 
第二種:
採用先對火車編號進行排列組合,計算出所有可能的出站情況。但是火車出站的情況需要滿足棧的出棧順序,所以通
火車編號的順序排列組合的順序進行出棧和入棧來比較排列組合中的
一組順序是否滿足條件,如果滿足,則該排 序就是有效的出棧順序。
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;
			//計算n個火車的出站的編號的排列組合
			ArrayList<int[]> result = new ArrayList<int[]>();
			Permutation(A,start,n,result);
			//出棧的結果,一個元素一個記錄,例如:1 2 3 ; 1 3 2 
			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());
				}
			}
			//最後輸出所有的符合出棧要求的組合
			for(String list:sortResult){
				System.out. println(list);
			} 
		}
		in.close();
	}
	/*in : 火車編號數組
	out : 火車出站順序
	n : 火 車 數 量
	*/
	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;
		}
		
		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; 
		}
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章