貓狗收容所(使用佇列實現)
1. 問題描述:
有家動物收容所只收留貓和狗,但有特殊的收養規則,收養人有兩種收養方式,
第一種為直接收養所有動物中最早進入收容所的,
第二種為選擇收養的動物型別(貓或狗),並收養該種動物中最早進入收容所的。
給定一個操作序列int[][2] ope(C++中為vector<vector<int>>)代表所有事件。
若第一個元素為1,則代表有動物進入收容所,第二個元素為動物的編號,正數代表狗,負數代表貓;
若第一個元素為2,則代表有人收養動物,第二個元素若為0,則採取第一種收養方式(最早進入收容所的貓/狗),
若為1,則指定收養狗,若為-1則指定收養貓。
請按順序返回收養的序列。若出現不合法的操作,即沒有可以符合領養要求的動物,則將這次領養操作忽略。
測試樣例:
[[1,1],[1,-1],[2,0],[2,-1]]
返回:[1,-1]
2. ① 從題目中我們可以知道需要按照時間順序求解出收養動物編號的序列,而且控制檯輸入的情況不同,對應的收養情況也會不同,其實這裡蘊含著某種資料結構的特點,為“先進先出”,先進來的動物是最早可能被收養的,所以我們可以使用佇列這種資料結構來儲存其中的資料
② 我們可以使用兩個佇列,一個是貓的佇列,一個是狗的佇列這樣可以方便我們入隊和出隊,當操作序列的第一個元素為1的時候我們就入隊,根據操作序列的第二個元素我們可以知道入的是貓隊還是狗隊
當操作序列的第一個元素為2的時候我們需要出隊,根據操作序列的第二個元素假如元素為1而且狗隊裡面的元素不為空的話我們就從狗隊裡面出一個元素,元素為-1而且貓隊裡面的元素不為空的話我們就從貓隊裡面出一個元素
元素為0的時候這個時候就要比較貓的隊首元素和狗的隊首元素入收容所的時間,怎麼樣知道這個時間呢?我們知道進入佇列肯定時間有先有後那麼我們可以在入隊的時候就記錄這個時間,等到檢視隊首元素的時候我們就知道這個時間瞭然後進行比較就可以了
③ 我們可以在一開始建立佇列的時候就可以把佇列裡面的資料型別設定為一個物件,利用物件可以封裝對應的屬性的特點,往物件中增加時間這個屬性這樣我們就可以在一建立這個物件的時候就把入隊的時間進行記錄下來,這裡可以使用設定一個全域性變數來進行時間的記錄,然後再建立物件的時候這個全域性變數的值加一然後賦值給這個物件中的時間屬性,注意這裡的類是私有的內部類,而且必須宣告成static
private static int timeCur;
public Animal(int typeNumber) {
super();
this.typeNumber = typeNumber;
this.time = timeCur++;}
這樣我們就在檢視兩個佇列的隊首元素的時候就知道入隊的時間先後順序了
凡是涉及到要封裝屬性的都可以使用私有的內部類來進行記錄和處理,接下里就是根據題目的要求進行簡單的邏輯判斷入隊,出隊即可,比較時間的先後順序即可
3. 具體的程式碼如下:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Main{
private static int timeCur = 1;
private static class Animal{
private int typeNumber;
private int time;
public Animal(int typeNumber) {
super();
this.typeNumber = typeNumber;
this.time = timeCur++;
}
@Override
public String toString() {
return "Animal [typeNumber=" + typeNumber + ", time=" + time + "]";
}
}
public static void main(String[] args) {
int[][] data = {{1, 1}, {1, -1}, {1, 0}, {1, 1}, {1, -5}, {2, 0}, {2, -1}, {2, 0}};
System.out.println(catAndDogAsyLum(data));
}
private static ArrayList<Integer> catAndDogAsyLum(int opValue[][]){
Queue<Animal> cats = new LinkedList<Animal>();
Queue<Animal> dogs = new LinkedList<Animal>();
ArrayList<Integer> res = new ArrayList<Integer>();
for(int opVal[] : opValue){
int opCode = opVal[0];
int value = opVal[1];
if(opCode == 1){
if(value > 0){
Animal dog = new Animal(value);
dogs.add(dog);
}
if(value < 0){
Animal cat = new Animal(value);
cats.add(cat);
}
}else if(opCode == 2){
if(!dogs.isEmpty() && value == 1){
res.add(dogs.poll().typeNumber);
}
if(!cats.isEmpty() && value == -1){
res.add(cats.poll().typeNumber);
}
if(value == 0){
if(dogs.isEmpty() && !cats.isEmpty()){
res.add(cats.poll().typeNumber);
}
else if(!dogs.isEmpty() && cats.isEmpty()){
res.add(dogs.poll().typeNumber);
}else if(!dogs.isEmpty() && !cats.isEmpty()){
int type = dogs.peek().time > cats.peek().time ? cats.poll().typeNumber: dogs.poll().typeNumber;
res.add(type);
}
}
}else{
break;
}
}
return res;
}
}