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

思路总结

  • 使用双向链表来管理考场的座位,便于在任意位置插入和删除座位。
  • 分配座位时,优先考虑最大化相邻座位间的间隔,以尽可能均匀地分布考生。
  • 释放座位时,需要更新链表结构,保持链表的完整性。
  • 在使用完毕后,需要释放所有分配的内存资源,避免内存泄漏。
相关推荐
AAA.建材批发刘哥17 分钟前
Linux快速入门-Linux文件系统管理
linux·运维·服务器·c语言·学习方法
cwj&xyp1 小时前
Python(二)str、list、tuple、dict、set
前端·python·算法
dlnu20152506221 小时前
ssr实现方案
前端·javascript·ssr
古木20191 小时前
前端面试宝典
前端·面试·职场和发展
Kisorge2 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味3 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王3 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发3 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀4 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js