855. 考场就座

题目:

在考场里,一排有 N 个座位,分别编号为 0, 1, 2, ..., N-1 。

当学生进入考场后,他必须坐在能够使他与离他最近的人之间的距离达到最大化的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 号座位上。)

返回 ExamRoom(int N) 类,它有两个公开的函数:其中,函数 ExamRoom.seat() 会返回一个 int (整型数据),代表学生坐的位置;函数 ExamRoom.leave(int p) 代表坐在座位 p 上的学生现在离开了考场。请确保每次调用 ExamRoom.leave(p) 时都有学生坐在座位 p 上。

 

示例:

输入:["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]]
输出:[null,0,9,4,2,null,5]
解释:
ExamRoom(10) -> null
seat() -> 0,没有人在考场里,那么学生坐在 0 号座位上。
seat() -> 9,学生最后坐在 9 号座位上。
seat() -> 4,学生最后坐在 4 号座位上。
seat() -> 2,学生最后坐在 2 号座位上。
leave(4) -> null
seat() -> 5,学生最后坐在 5 号座位上。

 

提示:

  1. 1 <= N <= 10^9
  2. 在所有的测试样例中 ExamRoom.seat() 和 ExamRoom.leave() 最多被调用 10^4 次。
  3. 调用 ExamRoom.leave(p) 时需要确保当前有学生坐在座位 p 上。

解析:

     这道题,我们维护一张排好序的set集合,集合用来保存已经有位置的座位序号,每次找到最大距离的最小坐标即可,当人离开的时候,我们把位置删掉即可,具体代码如下 :


class ExamRoom {
public:
    int last_seat;
    set<int> room_seat;
    ExamRoom(int N) {
        last_seat = N - 1;
    }
    
    int seat() {
        if(room_seat.size() == 0){
            room_seat.insert(0);
            return 0;
        }
        int i = 0;
        auto it = room_seat.begin();
        int pre_seat = *it;
        int distance = pre_seat - i;
        for(; it != room_seat.end(); it++){
            if((*it - pre_seat) / 2 > distance) {
                    distance = (*it - pre_seat) / 2;
                    i = pre_seat + distance;
                }
            pre_seat = *it;
        }
        if(last_seat - pre_seat > distance) i = last_seat;
        room_seat.insert(i);
        return i;
    }
    
    void leave(int p) {
        room_seat.erase(p);
    }
};

猜你喜欢

转载自blog.csdn.net/Torch_Man/article/details/80718999