LeetCode examination room seating

Disclaimer: This article is a blogger original articles, blog address: https: //blog.csdn.net/qq_41855420, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qq_41855420/article/details/90769754

In the examination room, a row of seats N, numbered 0, 1, 2, ..., N-1.

When students enter the examination room, he must be able to sit between him and his distance from the nearest person to achieve the maximization of the seat. If there are several such seats, he would sit on a minimum number of seats. (In addition, if no one in the examination room, the students sat on the seat number 0.)

Back ExamRoom (int N) class, which has two functions disclosed: where the function ExamRoom.seat () returns an int (integer data), representative of the student sitting position; function ExamRoom.leave (int p) representative of seat students in the p seat now left the examination room. It is guaranteed every time ExamRoom.leave§ call a student sitting in the seat p.

Example:

输入:["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 号座位上。

prompt:

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

think road \ Color {blue} thinking analysis: This question is to make our people furthest from the vicinity of each location to find, andLeetCode the maximum distance to the nearest humanThis question is essentially the same, more egg-type test data this question, need to be optimized.
First be written along the lines of the previous question.

class ExamRoom {
public:
    int N;//所有座位的个数
    int haveSeated;//已经座了人的座位数
    vector<int> mySeats;//存储各个座位的状态
    ExamRoom(int N) {
        this->N = N;//执行初始化操作
        haveSeated = 0;
        mySeats = vector<int>(N, 0);
    }
    
    int seat() {
    	//maxDis 是当前找到的离附近的人最远的间隔数,maxInsert 是对应的下标(坐的位置)
        int maxDis = 0, maxInsert = 0, index = 0;
        //检测第0个位置是否有人坐(也就是最前端是否有空位置段)
        while (index < N && mySeats[index] == 0){
            ++index;
        }
        maxDis = index;//前端出现空位置段初始化为坐在第0个位置,否则index = 0,也可以初始化为第0个位置
        maxInsert = 0;
        while (index < N){
            //跳过坐了人的位置
            while (index < N && mySeats[index] == 1){
                ++index;
            }
            //确定连续空位置区间
            int beforeIndex = index - 1;//beforeIndex记录空位置段的前一个坐了人的下标
            while (index < N && mySeats[index] == 0){
                ++index;
            }
            //更新最大结果
            if (index == N){
                //连续的空位置出现尾端,坐在尾端
                if (maxDis < index - beforeIndex - 1){
                    maxInsert = N - 1;
                    maxDis = index - beforeIndex - 1;
                }
            }
            else if (maxDis < (index - beforeIndex) / 2){//坐在空位置段的中间
                maxDis = (index - beforeIndex) / 2;
                maxInsert = beforeIndex + (index - beforeIndex) / 2;
            }
        }
        haveSeated += 1;
        mySeats[maxInsert] = 1;
        return maxInsert;
    }
    
    void leave(int p) {
        mySeats[p] = 0;
        haveSeated -= 1;
    }
};

/**
 * Your ExamRoom object will be instantiated and called as such:
 * ExamRoom* obj = new ExamRoom(N);
 * int param_1 = obj->seat();
 * obj->leave(p);
 */

Here Insert Picture Description
This algorithm greatly determine when N is relatively large, it scans every time the status of each seat, and then judge, that we can not shorten the number of cases each judge it? The answer is obvious, as long as we retain the position of the person sitting next standard, each looking for a pre-subscript empty position segment, the shift index, so that you can directly calculate the position meets the requirements of this section in.

class ExamRoom {
public:
    int N;
    int haveSeated;
    set<int> mySeats;//存放已经坐了人的位置下标
    ExamRoom(int N) {
        this->N = N;
        haveSeated = 0;
    }
    
    int seat() {
        //maxDis 是当前找到的离附近的人最远的间隔数,maxInsert 是对应的下标(坐的位置)
        int maxDis = 0, maxInsert = 0;
        if (haveSeated == 0){
            //考场里没有人,那么学生就坐在 0 号座位上
            maxDis = N;
            maxInsert = 0;
        }
        else{
            if (*mySeats.begin() != 0){
                //第0个位置没有人坐,初始化为坐在第0个位置
                maxDis = *mySeats.begin();
            }
            for (auto it = ++mySeats.begin(); it != mySeats.end(); ++it){
                int beforeIndex = *(--it);//空位置段前一个位置
                int endIndex = *(++it);//空位置段后一个位置
                //(endIndex - beforeIndex) / 2 在这个空位置段离附近的人最远的距离
                if (endIndex > beforeIndex && maxDis < (endIndex - beforeIndex) / 2){
                    maxDis = (endIndex - beforeIndex) / 2;
                    maxInsert = beforeIndex + maxDis;
                }
            }
            //如果N - 1这个位置没有人坐,并且坐在N - 1这个位置更恰当(离附近的人最远的距离)
            if (N - 1 - *(--mySeats.end()) > maxDis){
                maxInsert = N - 1;
            }
        }
        haveSeated += 1;
        mySeats.insert(maxInsert);
        return maxInsert;
    }
    
    void leave(int p) {
        haveSeated -= 1;
        mySeats.erase(p);
    }
};

/**
 * Your ExamRoom object will be instantiated and called as such:
 * ExamRoom* obj = new ExamRoom(N);
 * int param_1 = obj->seat();
 * obj->leave(p);
 */

Here Insert Picture Description

Guess you like

Origin blog.csdn.net/qq_41855420/article/details/90769754