https://www.nowcoder.com/questionTerminal/6235a76b1e404f748f7c820583125c50
https://blog.csdn.net/hj605635529/article/details/70876254
因为先进先出,用两个队列来表示收养所,猫队列的头部就是最早进入收留所的猫,狗队列的头部就是最早进入收留所的狗,
但是这种形式我们不能确定第一个进入的猫和第一个进入的狗谁最早进入,所以我们想到当入队列的时候,把动物的时间也压入。用一个额外的int变量来表示时序。
有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。
给定一个操作序列int[][2] ope(C++中为vector<vector<int>>)代表所有事件。若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫;若第一个元素为2,则代表有人收养动物,第二个元素若为0,则采取第一种收养方式,若为1,则指定收养狗,若为-1则指定收养猫。请按顺序返回收养的序列。若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。
https://blog.csdn.net/qq_39445165/article/details/84796849
给定一个操作序列int[][2] ope(C++中为vector<vector<int>>)代表所有事件。若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫;若第一个元素为2,则代表有人收养动物,第二个元素若为0,则采取第一种收养方式,若为1,则指定收养狗,若为-1则指定收养猫。请按顺序返回收养的序列。若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。
测试样例:
[[1,1],[1,-1],[2,0],[2,-1]]
返回:[1,-1]
https://blog.csdn.net/qq_39445165/article/details/84796849
2. 思路分析:① 从题目中我们可以知道需要按照时间顺序求解出收养动物编号的序列,而且控制台输入的情况不同,对应的收养情况也会不同,其实这里蕴含着某种数据结构的特点,为“先进先出”,先进来的动物是最早可能被收养的,所以我们可以使用队列这种数据结构来存储其中的数据
② 我们可以使用两个队列,一个是猫的队列,一个是狗的队列这样可以方便我们入队和出队,当操作序列的第一个元素为1的时候我们就入队,根据操作序列的第二个元素我们可以知道入的是猫队还是狗队
当操作序列的第一个元素为2的时候我们需要出队,根据操作序列的第二个元素假如元素为1而且狗队里面的元素不为空的话我们就从狗队里面出一个元素,元素为-1而且猫队里面的元素不为空的话我们就从猫队里面出一个元素
元素为0的时候这个时候就要比较猫的队首元素和狗的队首元素入收容所的时间,怎么样知道这个时间呢?我们知道进入队列肯定时间有先有后那么我们可以在入队的时候就记录这个时间,等到查看队首元素的时候我们就知道这个时间了然后进行比较就可以了
③ 我们可以在一开始创建队列的时候就可以把队列里面的数据类型设置为一个对象,利用对象可以封装对应的属性的特点,往对象中增加时间这个属性这样我们就可以在一创建这个对象的时候就把入队的时间进行记录下来,这里可以使用设置一个全局变量来进行时间的记录,然后再创建对象的时候这个全局变量的值加一然后赋值给这个对象中的时间属性,注意这里的类是私有的内部类,而且必须声明成static
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 + "]";
}
}
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;
}
https://blog.csdn.net/hj605635529/article/details/70876254
因为先进先出,用两个队列来表示收养所,猫队列的头部就是最早进入收留所的猫,狗队列的头部就是最早进入收留所的狗,
但是这种形式我们不能确定第一个进入的猫和第一个进入的狗谁最早进入,所以我们想到当入队列的时候,把动物的时间也压入。用一个额外的int变量来表示时序。
vector<int> Asylum(vector<vector<int> > ope)
{
queue<int> cat;
queue<int> dog;
vector<int> ret;
int idx = 0; //表示时间。
for(int i = 0; i < ope.size(); ++i)
{
if(ope[i][0] == 1) //有动物要进收养所了。
{
if(ope[i][1] > 0) //编号大于0,表示狗进入
{
dog.push(idx++); //把动物的时序也一并压入。
dog.push(ope[i][1]);
}
else
{
cat.push(idx++);
cat.push(ope[i][1]);
}
}
if(ope[i][0] == 2) //表示有人要收养动物了。
{
if(ope[i][1] == 0) //第一种方式收养,收养最早的动物。
{
int catidx = cat.empty() ? 10000000 :cat.front();
int dogidx = dog.empty() ? 10000000 :dog.front();
if(catidx < dogidx)
{
cat.pop(); //把时序弹出。
ret.push_back(cat.front() );
cat.pop();
}
else
{
dog.pop(); //把时序弹出。
ret.push_back(dog.front() );
dog.pop();
}
}
else if(ope[i][1] == 1) //第二种方式收养,收养狗
{
if(!dog.empty())
{
dog.pop(); //把时序弹出。
ret.push_back(dog.front() );
dog.pop();
}
}
else
{
if(!cat.empty() )
{
cat.pop(); //把时序弹出。
ret.push_back(cat.front() );
cat.pop();
}
}
}
}
return ret;
}