Leetcode打卡:考场就坐

执行结果:通过

题目: 855 考场就坐

在考场里,有 n 个座位排成一行,编号为 0n - 1

当学生进入考场后,他必须坐在离最近的人最远的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 号座位上。)

设计一个模拟所述考场的类。

实现 ExamRoom 类:

  • ExamRoom(int n) 用座位的数量 n 初始化考场对象。
  • int seat() 返回下一个学生将会入座的座位编号。
  • void leave(int p) 指定坐在座位 p 的学生将离开教室。保证座位 p 上会有一位学生。

示例 1:

复制代码
输入:
["ExamRoom", "seat", "seat", "seat", "seat", "leave", "seat"]
[[10], [], [], [], [], [4], []]
输出:
[null, 0, 9, 4, 2, null, 5]
解释:
ExamRoom examRoom = new ExamRoom(10);
examRoom.seat(); // 返回 0,房间里没有人,学生坐在 0 号座位。
examRoom.seat(); // 返回 9,学生最后坐在 9 号座位。
examRoom.seat(); // 返回 4,学生最后坐在 4 号座位。
examRoom.seat(); // 返回 2,学生最后坐在 2 号座位。
examRoom.leave(4);
examRoom.seat(); // 返回 5,学生最后坐在 5 号座位。

提示:

  1. 1 <= n <= 109
  2. 保证有学生正坐在座位 p 上。
  3. seatleave 最多被调用 104 次。

代码以及解题思路

代码:

typedef struct mylink {
    int id;
    struct mylink *next;
} mylink;


typedef struct {
    int length;
    mylink* root;
} ExamRoom;
void print_obj(ExamRoom *obj)
{
    printf("%d ",obj->length);
    mylink* tmp=obj->root;
    while(tmp!=NULL)
    {
        printf("%d ",tmp->id);
        tmp=tmp->next;
    }
    printf("\n");
}


ExamRoom* examRoomCreate(int n) {
     ExamRoom* obj=malloc(sizeof(ExamRoom));
    obj->length=n;
    obj->root=NULL;
    return obj;

}

int examRoomSeat(ExamRoom* obj) {
    if(obj->root==NULL)
    {
        obj->root=malloc(sizeof(mylink));
        obj->root->id=0;
        obj->root->next=NULL;
        return 0;
    }
    int max=-1;
    if(obj->root->id!=0) max=obj->root->id;
    mylink* max_link_before=NULL;
    mylink* tmp=obj->root;
    int diff=0;
    while(tmp->next!=NULL)
    {   
        diff=(tmp->next->id - tmp->id)/2;
        if(diff>max)
        {
            max=diff;
            max_link_before=tmp;
        }
        tmp=tmp->next;
    }
    //tmp 为末尾时
    diff=obj->length -1 - tmp->id;
    if(diff>max)
    {
        max=diff;
        max_link_before=tmp;
    }
    if(max_link_before==NULL)
    {
        mylink* add=malloc(sizeof(mylink));
        add->id=0;
        add->next=obj->root;
        obj->root=add;
        return 0;
    }
    if(max_link_before->next==NULL)
    {
        max_link_before->next=malloc(sizeof(mylink));
        max_link_before->next->id=obj->length-1;
        max_link_before->next->next=NULL;
        return obj->length-1;
    }
    else
    {
        mylink* add=malloc(sizeof(mylink));
        add->id=max_link_before->id + max;
        add->next=max_link_before->next;
        max_link_before->next=add;
        return add->id;
    }

}

void examRoomLeave(ExamRoom* obj, int p) {
     mylink* tmp=obj->root;
    mylink* before=NULL;
    while(tmp!=NULL)
    {
        if(tmp->id==p)
        {
            if(before==NULL)
            {
                obj->root=tmp->next;
                free(tmp);
            }
            else
            {
                before->next=tmp->next;

                free(tmp);
            }
            return;
        }
        before=tmp;
        tmp=tmp->next;
    }

}

void examRoomFree(ExamRoom* obj) {
    mylink* tmp=obj->root;
    mylink* next;
    while(tmp!=NULL)
    {
        next=tmp->next;
        free(tmp);
        tmp=next;
    }
    free(obj);

}

解题思路:

1. 数据结构定义

  • mylink 结构体:表示链表中的一个节点,包含座位号 id 和指向下一个节点的指针 next
  • ExamRoom 结构体:表示考场,包含两个成员:length 表示考场总座位数,root 指向链表的头节点。
  • 作用:打印考场信息,包括总座位数和已分配的座位号。
  • 解题思路 :首先打印总座位数 length,然后遍历链表,打印每个节点的座位号 id

3. examRoomCreate 函数

  • 作用:创建一个新的考场对象。
  • 解题思路 :使用 malloc 分配 ExamRoom 结构体所需的内存,初始化 length 为传入的参数 nroot 初始化为 NULL(表示链表为空),最后返回创建的考场对象。

4. examRoomSeat 函数

  • 作用:在考场中分配一个座位,并返回分配的座位号。
  • 解题思路
    1. 如果链表为空(即还没有分配任何座位),则在链表头部插入一个座位号为 0 的节点,并返回 0
    2. 遍历链表,计算相邻座位之间的最大间距 max 和该间距前的节点 max_link_before
    3. 考虑链表末尾与最后一个座位之间的间距。
    4. 根据 max_link_before 的值,在最大间距处插入一个新节点:
      • 如果 max_link_beforeNULL,则在链表头部插入新节点。
      • 如果 max_link_before->nextNULL,则在链表尾部插入新节点。
      • 否则,在 max_link_beforemax_link_before->next 之间插入新节点。
    5. 新节点的座位号 idmax_link_before->id + max,然后返回新节点的座位号。

5. examRoomLeave 函数

  • 作用:释放一个座位。
  • 解题思路 :遍历链表,找到座位号为 p 的节点,并将其从链表中删除。如果要删除的节点是头节点,则更新头节点为下一个节点;否则,更新前一个节点的 next 指针,跳过要删除的节点。最后释放要删除的节点的内存。

6. examRoomFree 函数

  • 作用:释放考场对象及其占用的所有内存。
  • 解题思路:遍历链表,释放每个节点的内存,然后释放考场对象本身的内存。
相关推荐
半桔4 分钟前
七大排序思想
c语言·开发语言·数据结构·c++·算法·排序算法
吴秋霖1 小时前
某音小程序反编译签名加密静态分析
python·算法·小程序
fajianchen1 小时前
图文并茂-jvm内存模型
java·jvm·算法
️Carrie️1 小时前
1.1 画质算法的主要任务
图像处理·算法·图像画质算法·底层视觉
呆呆的猫1 小时前
【LeetCode】152、乘积最大子数组
算法·leetcode·职场和发展
云卓SKYDROID1 小时前
无人机使用数传时的注意事项!
科技·算法·无人机·科普·云卓科技
hurrycry_小亦2 小时前
洛谷题目: P8774 [蓝桥杯 2022 省 A] 爬树的甲壳虫 题解 (本题较简)
算法·职场和发展·蓝桥杯
Power++3 小时前
【BUUCTF逆向题】[MRCTF2020]Transform
python·算法·系统安全·密码学·代码复审
陪你去流浪_3 小时前
Vue el-input密码输入框 按住显示密码,松开显示*;阻止浏览器密码回填,自写密码输入框;校验输入非汉字内容;文本框聚焦到内容末尾;
前端·javascript·vue.js
robin_suli3 小时前
穷举vs暴搜vs深搜vs回溯vs剪枝系列一>黄金矿工
算法·剪枝·深度优先遍历·回溯