Leecode刷题C语言之考场就座

执行结果:通过

执行用时和内存消耗如下:

复制代码
typedef struct _Seat {
    int id;
    struct _Seat* prev;
    struct _Seat* next;
} Seat;

typedef struct _ExamRoom {
    int     cap;
    int     cnt;
    Seat* head;
} ExamRoom;

ExamRoom* examRoomCreate(int n) {
    ExamRoom* ret = (ExamRoom * )calloc(sizeof(ExamRoom), 1);
    ret->cap = n;
    return ret;
}

int examRoomSeat(ExamRoom* obj) {
    Seat* seat = (Seat * )calloc(sizeof(Seat), 1);
    Seat* p;
    Seat* maxGapSeat = 0;
    int   maxGap = 0;
    int   i, gap;

    switch (obj->cnt) {
    case 0:
        seat->id = 0;
        obj->head = seat;
        break;
    case 1:
        if (obj->cap - 1 - obj->head->id > obj->head->id) {
            seat->id = obj->cap - 1;
            obj->head->next = seat;
            seat->prev = obj->head;
        }
        else {
            seat->id = 0;
            seat->next = obj->head;
            obj->head->prev = seat;
            obj->head = seat;
        }
        break;
    default:
        for (i = 0, p = obj->head; i < obj->cnt; i++, p = p->next) {
            if ((i == 0) && (p->id != 0)) {
                gap = p->id;
                maxGap = gap;
                maxGapSeat = 0;
            }
            else if (i == obj->cnt - 1) {
                if (p->id != obj->cap - 1) {
                    gap = obj->cap - 1 - p->id;
                    if (maxGap < gap) {
                        maxGap = gap;
                        maxGapSeat = p;
                    }
                }
                else {
                    gap = (p->prev->id + p->id) / 2 - p->prev->id;
                    if (maxGap < gap) {
                        maxGap = gap;
                        maxGapSeat = p->prev;
                    }
                }
            }
            else {
                gap = (p->next->id + p->id) / 2 - p->id;
                if (maxGap < gap) {
                    maxGap = gap;
                    maxGapSeat = p;
                }
            }
        }

        if (maxGapSeat == 0) {
            seat->id = 0;
            seat->next = obj->head;
            obj->head->prev = seat;
            obj->head = seat;
        }
        else {
            seat->id = maxGapSeat->id + maxGap;
            seat->prev = maxGapSeat;
            if (maxGapSeat->next) {
                seat->next = maxGapSeat->next;
                maxGapSeat->next->prev = seat;
            }
            maxGapSeat->next = seat;
        }
        break;
    }
    obj->cnt++;
    return seat->id;
}

void examRoomLeave(ExamRoom* obj, int seat) {
    Seat* p;
    int i;
    for (i = 0, p = obj->head; i < obj->cnt; i++, p = p->next) {
        if (p->id == seat) {
            if (i == 0) {
                obj->head = p->next;
                if (p->next) {
                    p->next->prev = 0;
                }
            }
            else if (i == obj->cnt - 1) {
                p->prev->next = 0;
            }
            else {
                p->prev->next = p->next;
                p->next->prev = p->prev;
            }
            free(p);
            obj->cnt--;
            break;
        }
    }
}

void examRoomFree(ExamRoom* obj) {

}

解题思路如下 :

这段代码实现了一个简单的考场座位管理系统,其中包含了创建考场、分配座位、释放座位和释放考场资源的功能。下面是代码的具体思路:

结构体定义

  1. Seat 结构体

    • int id:座位编号。
    • struct _Seat* prev:指向前一个座位的指针。
    • struct _Seat* next:指向下一个座位的指针。

    这个结构体用于表示考场中的座位,座位之间通过双向链表连接。

  2. ExamRoom 结构体

    • int cap:考场容量,即最大座位数。
    • int cnt:当前已分配的座位数。
    • Seat* head:指向考场座位链表的头节点的指针。

    这个结构体用于表示整个考场,包含考场的基本信息和座位链表。

函数实现

  1. examRoomCreate(int n)
    • 创建一个新的 ExamRoom 实例。
    • 分配内存并初始化,设置考场的容量为 n
    • 返回创建的 ExamRoom 实例的指针。
  2. *examRoomSeat(ExamRoom obj)**:
    • 在考场 obj 中分配一个座位。
    • 如果考场为空(cnt == 0),则分配第一个座位(id = 0)。
    • 如果考场中有一个座位(cnt == 1),则根据剩余空间的大小,在头或尾分配第二个座位。
    • 如果考场中有多个座位(cnt > 1),则遍历座位链表,找到相邻座位间最大间隔的位置,并在此位置分配一个新座位。间隔的计算考虑了首尾座位之间的间隔。
    • 更新考场中的座位数 cnt
    • 返回新分配座位的编号。
  3. *examRoomLeave(ExamRoom obj, int seat)**:
    • 释放考场 obj 中的指定座位 seat
    • 遍历座位链表,找到座位编号为 seat 的座位节点。
    • 根据该座位在链表中的位置,更新前后座位的指针,将其从链表中移除。
    • 释放该座位节点的内存。
    • 更新考场中的座位数 cnt
  4. *examRoomFree(ExamRoom obj)**:
    • 释放考场 obj 的所有资源。
    • 此函数在提供的代码中是空的,需要实现遍历座位链表并释放所有座位节点的内存,最后释放 ExamRoom 实例的内存。

思路总结

  • 使用双向链表来管理考场的座位,便于在任意位置插入和删除座位。
  • 分配座位时,优先考虑最大化相邻座位间的间隔,以尽可能均匀地分布考生。
  • 释放座位时,需要更新链表结构,保持链表的完整性。
  • 在使用完毕后,需要释放所有分配的内存资源,避免内存泄漏。
相关推荐
进取星辰12 分钟前
25、Tailwind:魔法速记术——React 19 样式新思路
前端·react.js·前端框架
struggle202531 分钟前
continue通过我们的开源 IDE 扩展和模型、规则、提示、文档和其他构建块中心,创建、共享和使用自定义 AI 代码助手
javascript·ide·python·typescript·开源
我叫珂蛋儿吖37 分钟前
[redis进阶六]详解redis作为缓存&&分布式锁
运维·c语言·数据库·c++·redis·分布式·缓存
x-cmd1 小时前
[250512] Node.js 24 发布:ClangCL 构建,升级 V8 引擎、集成 npm 11
前端·javascript·windows·npm·node.js
夏之小星星1 小时前
el-tree结合checkbox实现数据回显
前端·javascript·vue.js
周Echo周1 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
crazyme_61 小时前
前端自学入门:HTML 基础详解与学习路线指引
前端·学习·html
安装虚拟机的老师傅2 小时前
【2025最新】Windows系统装VSCode搭建C/C++开发环境(附带所有安装包)
c语言·windows·vscode·其他
撸猫7912 小时前
HttpSession 的运行原理
前端·后端·cookie·httpsession
亦世凡华、2 小时前
Rollup入门与进阶:为现代Web应用构建超小的打包文件
前端·经验分享·rollup·配置项目·前端分享