力扣面试题 23 - 动物收容所

题目:

动物收容所。有家动物收容所只收容狗与猫,且严格遵守“先进先出”的原则。在收养该收容所的动物时,收养人只能收养所有动物中“最老”(由其进入收容所的时间长短而定)的动物,或者可以挑选猫或狗(同时必须收养此类动物中“最老”的)。换言之,收养人不能自由挑选想收养的对象。请创建适用于这个系统的数据结构,实现各种操作方法,比如enqueuedequeueAnydequeueDogdequeueCat。允许使用Java内置的LinkedList数据结构。

enqueue方法有一个animal参数,animal[0]代表动物编号,animal[1]代表动物种类,其中 0 代表猫,1 代表狗。

dequeue*方法返回一个列表[动物编号, 动物种类],若没有可以收养的动物,则返回[-1,-1]

示例1:

 输入:
["AnimalShelf", "enqueue", "enqueue", "dequeueCat", "dequeueDog", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [], [], []]
 输出:
[null,null,null,[0,0],[-1,-1],[1,0]]

示例2:

 输入:
["AnimalShelf", "enqueue", "enqueue", "enqueue", "dequeueDog", "dequeueCat", "dequeueAny"]
[[], [[0, 0]], [[1, 0]], [[2, 1]], [], [], []]
 输出:
[null,null,null,null,[2,1],[0,0],[1,0]]

说明:

  1. 收纳所的最大容量为20000

思路:

  1. 使用一个双端链表的结构来表示动物队列。队列包含两种类型的动物:猫和狗。每个动物节点包含其编号和种类信息。
  2. 收养动物但不指定猫还是狗时,如何判断谁更“老”呢?可以通过比较序号的方式判断。

具体函数设计:

1. 数据结构设计

  • 使用了一个双端链表的结构来表示动物队列。队列包含两种类型的动物:猫和狗。每个动物节点包含其编号和种类信息。
  • 使用 *head*tail 分别表示队列的头部和尾部指针,便于在队列两端进行操作。
  • 需要分别处理猫、狗和任意动物的入队和出队操作。

2. animalShelfCreate 创建队列

  • 初始化一个空的 AnimalShelf 结构体,其中 headtail 都初始化为 NULL,表示队列为空。

3. animalShelfEnqueue 入队操作

  • 根据传入的动物数据(编号和种类),创建一个新的动物节点。
  • 如果队列为空(即 *tail == NULL),将新的动物节点作为队列的第一个元素,*head*tail 都指向该节点。
  • 如果队列不为空,则根据动物种类(猫或狗)将新节点添加到对应的队列末尾,更新 *tail

4. animalShelfDequeueAny 任意出队操作

  • 判断队列是否为空。如果队列为空,直接返回 NULL
  • 如果队列非空,返回头部节点(第一个入队的动物)。更新 *head,让它指向下一个动物节点。如果更新后队列为空,还需要将 *tail 置为 NULL

5. animalShelfDequeueDog 狗出队操作

  • 判断队列是否为空。如果为空,返回 NULL
  • 否则,从队列中寻找最早进入队列的狗并将其出队。更新头部指针 *head,并且如果队列为空,还需要将 *tail 置为 NULL

6. animalShelfDequeueCat 猫出队操作

  • 判断队列是否为空。如果为空,返回 NULL
  • 否则,从队列中寻找最早进入队列的猫并将其出队。更新头部指针 *head,并且如果队列为空,还需要将 *tail 置为 NULL

7. animalShelfFree 释放队列

  • 释放队列中所有节点的内存。

C代码如下:

// 定义 Animal 结构体
typedef struct Animal {
    int id;
    int type; // 0 表示猫,1 表示狗
    struct Animal* next;
} Animal;

// 定义 AnimalShelf 结构体
typedef struct {
    Animal* dogHead;
    Animal* catHead;
    Animal* dogTail;
    Animal* catTail;
} AnimalShelf;

// 创建 AnimalShelf
AnimalShelf* animalShelfCreate() {
    AnimalShelf* shelf = (AnimalShelf*)malloc(sizeof(AnimalShelf));
    shelf->dogHead = NULL;
    shelf->catHead = NULL;
    shelf->dogTail = NULL;
    shelf->catTail = NULL;
    return shelf;
}

// 辅助函数:将动物加入队列
void enqueueAnimal(Animal** head, Animal** tail, int id, int type) {
    Animal* newAnimal = (Animal*)malloc(sizeof(Animal));
    newAnimal->id = id;
    newAnimal->type = type;
    newAnimal->next = NULL;
    if (*tail) {
        (*tail)->next = newAnimal;
    } else {
        *head = newAnimal;
    }
    *tail = newAnimal;
}

// 辅助函数:从队列中移除动物
Animal* dequeueAnimal(Animal** head, Animal** tail) {
    if (!*head) return NULL;
    Animal* animal = *head;
    *head = (*head)->next;
    if (!*head) {
        *tail = NULL;
    }
    return animal;
}

int* animalShelfDequeueDog(AnimalShelf* obj, int* retSize);

int* animalShelfDequeueCat(AnimalShelf* obj, int* retSize);

// 加入动物
void animalShelfEnqueue(AnimalShelf* obj, int* animal, int animalSize) {
    if (animal[1] == 0) {
        enqueueAnimal(&obj->catHead, &obj->catTail, animal[0], animal[1]);
    } else if (animal[1] == 1) {
        enqueueAnimal(&obj->dogHead, &obj->dogTail, animal[0], animal[1]);
    }
}

// 收养任意动物
int* animalShelfDequeueAny(AnimalShelf* obj, int* retSize) {
    *retSize = 2;
    if (!obj->dogHead && !obj->catHead) {
        int* result = (int*)malloc(2 * sizeof(int));
        result[0] = -1;
        result[1] = -1;
        return result;
    }
    if (!obj->dogHead) return animalShelfDequeueCat(obj, retSize);
    if (!obj->catHead) return animalShelfDequeueDog(obj, retSize);

    if (obj->dogHead->id < obj->catHead->id) {
        return animalShelfDequeueDog(obj, retSize);
    } else {
        return animalShelfDequeueCat(obj, retSize);
    }
}

// 收养狗
int* animalShelfDequeueDog(AnimalShelf* obj, int* retSize) {
    *retSize = 2;
    Animal* dog = dequeueAnimal(&obj->dogHead, &obj->dogTail);
    if (!dog) {
        int* result = (int*)malloc(2 * sizeof(int));
        result[0] = -1;
        result[1] = -1;
        return result;
    }
    int* result = (int*)malloc(2 * sizeof(int));
    result[0] = dog->id;
    result[1] = dog->type;
    free(dog);
    return result;
}

// 收养猫
int* animalShelfDequeueCat(AnimalShelf* obj, int* retSize) {
    *retSize = 2;
    Animal* cat = dequeueAnimal(&obj->catHead, &obj->catTail);
    if (!cat) {
        int* result = (int*)malloc(2 * sizeof(int));
        result[0] = -1;
        result[1] = -1;
        return result;
    }
    int* result = (int*)malloc(2 * sizeof(int));
    result[0] = cat->id;
    result[1] = cat->type;
    free(cat);
    return result;
}

// 释放 AnimalShelf
void animalShelfFree(AnimalShelf* obj) {
    Animal* temp;
    while (obj->dogHead) {
        temp = obj->dogHead;
        obj->dogHead = obj->dogHead->next;
        free(temp);
    }
    while (obj->catHead) {
        temp = obj->catHead;
        obj->catHead = obj->catHead->next;
        free(temp);
    }
    free(obj);
}

动物招领所 一.前言: 该系统主要培养面向对象的思维方式。 二.使用的技术:(主要是下面这些技术,基本全部用到) 数组 包 类与对象 继承,重写,多态 抽象类,接口 static属性,static方法,static块 final属性,final方法,final类 三.面向对象的思考方式 将世界看成一个个对象,对象之间可以分类(包),可以相互有继承。面向对象推荐面向接口进行编程,面向接口的核心思想是抽象(只依赖于接口不依赖于具体的实现)这样来构造灵活的系统。 四.系统概述: 流浪动物招领所是收养流浪动物的地方,动物招领所有一定的粮食用来喂养动物动物保护者寻找流浪的动物,并带回到动物招领所喂养。 动物管理者照顾动物,每照顾一次,动物的体重会增加,每种动物增加的重量不同,体重的上限也不同。 招领所的动物可以被满足条件的领养者进行领养。有许多种领养者:工人,农民等 动物有许多种类别,但是都有一些公有的特征。 系统启动后,动物保护者可以随机发现动物(动物的种类可能不一样),加入动物园,由动物管理员进行照顾。招领所定期的将动物随机的交给领养者领养,领养后动物动物减少。 五.系统分析: 1:包的设计:动物(猫,狗,猪),领养者(农民,工人,公务员),动物招领所(招领所本身,动物保护者,动物管理者),工具包(Input输入辅助类) 2:动物的设计(使用到抽象类,继承,重写等)。动物是抽象类,提供动物的模板信息。各个具体的子类动物继承动物,每个动物在抽象类的基础上有相应的扩充 3:动物集合的设计:写一个类表示动物的集合,可以往里面加入动物(只要是动物就可以),可以删除动物,将所有动物信息打印出来三个方法. 4:领养者的设计(使用接口和实现)。领养规则是接口,具体的领养者实现了接口。 5:随机生成领养者的工厂(static方法,Math.random()类):有一方法newAdopter()随机产生一个领养者并返回 6:动物保护者的设计(使用static方法,Math.random()类):动物保护者有一方法discoverAnimal()能够发现动物.发现的过程如下:每次系统随机的产生一个数,如果是1,提示用户输入猫的信息,并使用这些信息创建一个猫,如果是2,提示用户输入狗的信息,使用这些信息创建一个狗,依次类推。最后将发现的动物返回。 7:动物饲养者的设计:一个类,负责饲养动物 7:招领所的设计:招领所是一个类,内部使用动物的集合保存动物,使用饲养者对动物进行照顾。招领所启动后运行系统,打印主菜单开始运行。 8:使用测试类的main方法实例化招领所,启动系统的运行。 9:系统有一个final类型的输入辅助类Input,里面的方法全是静态的,可以直接调用. 六.系统运行 -------系统运行菜单------ 1:发现动物 2:饲养动物 3:动物招领 4:列出所有动物 5:所有动物的特征 6:退出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值