火車進出站問題
給定一個正整數N代表火車數量,0<N<10,接下來輸入火車入站的序列,一共N輛火車,每輛火車以數字1-9編號。要求以字典序排序輸出火車出站的序列號。
解題思路:數組的全排序+出站順序的判定。
詳細過程:
1、數組的全排序:分治算法的經典。可參考:數組全排序。我這裏簡單說一下,利用分治思想將大問題化爲小問題,一共有n個元素,第一個位置上可以有n種選擇,第二個位置上有n-1種選擇,因此,對於當前位置i來講,將i後的所有元素都與i上的元素進行交換,若交換產生了全排序,則需要將原本i的元素再交換回來以供下次的交換使用。 由於是採用遞歸,只需要關注當前位置i上的所有可能即可,eg:
只需要關注i位置的3中不同選擇即可,前面的已被選好不需要關注,後面的還未選留給下次遞歸實現,本次遞歸也不需要關注。
對於該位置來講,後面的所有剩餘元素+當前該位置上的元素,都有可能位於當前位置上,因此,每次將當前位置上的元素替換爲之後剩餘元素中的某個值後,在該值處於當前位置獲取全排列結束後,需要將原來的值再替換回來,否則,會導致重複排列。
代碼實現:
public static void allSort(int[] arr,int start,int end,Queue<int[]> queue){
if (start==end){
queue.add(arr.clone());
}else {
for (int i = start; i <= end ; i++) {
swap(arr,start,i);
allSort(arr,start+1,end,queue);
swap(arr,start,i);
}
}
}
2、判斷數組pop是否能作爲數組arr的出棧數組:將arr數組中的元素依次加入到stack棧中,在每次加入後循環判斷棧頂元素(棧非空)與出棧數組pop中index(默認爲0)對應的值是否相同,若相同,則將該值出棧,並將index++,最終只需要判斷該棧是否爲空即可,爲空說明可以作爲出棧數組。
入棧的同時進行出棧操作,如果最終的棧爲空,說明棧中的元素全部出棧,也就說明當前出棧順序與入棧順序可以匹配。
代碼實現:
public static boolean isPop(int[] arr,int[] pop){
Stack<Integer> stack = new Stack<>();
int index = 0;
for (int i = 0; i < arr.length; i++) {
stack.push(arr[i]);
while (!stack.empty()&&pop[index]==stack.peek()){
stack.pop();
index++;
}
}
return stack.isEmpty();
}