LeetCode 855. Exam Room

LeetCode 855. Exam Room

传送门

题目分析

In an exam room, there are N seats in a single row, numbered 0, 1, 2, ..., N-1.

When a student enters the room, they must sit in the seat that maximizes the distance to the closest person. If there are multiple such seats, they sit in the seat with the lowest number. (Also, if no one is in the room, then the student sits at seat number 0.)

Return a class ExamRoom(int N) that exposes two functions: ExamRoom.seat() returning an int representing what seat the student sat in, and ExamRoom.leave(int p) representing that the student in seat number p now leaves the room. It is guaranteed that any calls to ExamRoom.leave(p) have a student sitting in seat p.

Example 1:

Input: ["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]]
Output: [null,0,9,4,2,null,5]
Explanation:
ExamRoom(10) -> null
seat() -> 0, no one is in the room, then the student sits at seat number 0.
seat() -> 9, the student sits at the last seat number 9.
seat() -> 4, the student sits at the last seat number 4.
seat() -> 2, the student sits at the last seat number 2.
leave(4) -> null
seat() -> 5, the student sits at the last seat number 5.

Note:

  1. 1 <= N <= 10^9
  2. ExamRoom.seat() and ExamRoom.leave() will be called at most 10^4 times across all test cases.
  3. Calls to ExamRoom.leave(p) are guaranteed to have a student currently sitting in seat number p.

思考

对有具体要求的数据结构实现,很难得的题目,题目要求明确,新建一个容量为N的考试房间,每次向里放人或者向外赶人,放人要求必须放在离其他人最远的位置,这个数据结构的放置范围在 1109 1 ∼ 10 9 ,直接使用数组模拟必然导致内存超出,所以我选用了内部元素有序的set来坐内部数据结构,每次先检查0和最后一个位置是否坐了人,毕竟这两个位置只需要考虑一边,而其它位置的的选取则必然是在两个座位中间选取,max_len变量记录最长的距离,idx记录上一个同学的位置,遍历set即可,删除时直接使用erase

代码实现

class ExamRoom {
public:
    set<int> seats;
    int n;
    ExamRoom(int N) {
        // 保存一下N
        n = N;
    }

    int seat() {
        // 寻找座位
        int result = 0;
        if (seats.size() != 0) {
            result = 0;
            int idx = 0;
            int max_len = 0;
            // 查看0是否占用
            if (!seats.count(0)) {
                // 注意,最后的那个位置和0处的距离是不需要除2的
                max_len = *seats.begin() - 0;
                result = 0;
            }
            auto it = seats.begin(), end = seats.end();
            while (it != end) {
                int len = (*it - idx) / 2;
                if (len > max_len) {
                    max_len = len;
                    result = (*it + idx) / 2;
                }
                idx = *it;
                ++it;
            }
            // 看最后的位置有没有被占
            if (!seats.count(n - 1)) {
                int len = n - 1 - *seats.rbegin();
                if (len > max_len) {
                    max_len = len;
                    result = n - 1;
                }
            }
        }

        seats.insert(result);
        return result;
    }

    void leave(int p) {
        seats.erase(seats.find(p));
    }
};

感想

这道题可以说是做的非常难受了,我在1h28m的时候才把它AC掉,虽然在Leetcode上碰到好几个这样的题,绝对算不上陌生,可是真的在比赛里碰见时才能发现自己的水平的真的不够,多加练习,学习新的算法和数据结构才能让自己的能力更上一层楼。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值