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 实例的内存。

思路总结

  • 使用双向链表来管理考场的座位,便于在任意位置插入和删除座位。
  • 分配座位时,优先考虑最大化相邻座位间的间隔,以尽可能均匀地分布考生。
  • 释放座位时,需要更新链表结构,保持链表的完整性。
  • 在使用完毕后,需要释放所有分配的内存资源,避免内存泄漏。
相关推荐
持力行6 小时前
从C struct到C++中的class
c语言·c++
meilindehuzi_a7 小时前
从零理解并实现 RAG:用 LangChain.js 构建语义检索问答系统
开发语言·javascript·langchain
世界哪有真情8 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
鱼樱前端8 小时前
别再自己拼凑了!这款 Vue 3.5+ 严肃产品级组件库,把 AI 对话、工作流和复杂数据全包了!
javascript·vue.js·github
Listen·Rain9 小时前
Vue3:setup详解
前端·javascript·vue.js
Patrick_Wilson9 小时前
修好 bug 只是开始:一次由监控需求反向重构日志结构的复盘
前端·监控·数据可视化
kyriewen10 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
小粉粉hhh10 小时前
React(二)——dom、组件间通信、useEffect
前端·javascript·react.js
Csvn11 小时前
🤖 AI 生成前端代码的 5 个典型翻车现场及修复指南
前端
2501_9142459311 小时前
C语言设计模式详解:从理论到实践的完整指南
c语言·开发语言·设计模式