855. 考场就座

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/exam-room
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

扫描当前学生

import java.util.TreeSet;

class ExamRoom {
    int N;
    TreeSet<Integer> students;

    public ExamRoom(int N) {
        this.N = N;
        students = new TreeSet();
    }

    public int seat() {
        //Let's determine student, the position of the next
        //student to sit down.
        int student = 0;
        if (students.size() > 0) {
            //Tenatively, dist is the distance to the closest student,
            //which is achieved by sitting in the position 'student'.
            //We start by considering the left-most seat.
            int dist = students.first();
            Integer prev = null;
            for (Integer s: students) {
                if (prev != null) {
                    //For each pair of adjacent students in positions (prev, s),
                    //d is the distance to the closest student;
                    //achieved at position prev + d.
                    int d = (s - prev) / 2;
                    if (d > dist) {
                        dist = d;
                        student = prev + d;
                    }
                }
                prev = s;
            }

            //Considering the right-most seat.
            if (N - 1 - students.last() > dist)
                student = N - 1;
        }

        //Add the student to our sorted TreeSet of positions.
        students.add(student);
        return student;
    }

    public void leave(int p) {
        students.remove(p);
    }
}

区间的优先队列

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

class ExamRoom {

    private int n;

    private TreeSet<int[]> segmentSet;

    private Map<Integer, Integer> leftMap;

    private Map<Integer, Integer> rightMap;

    private int distance(int[] o) {
        if (o[0] == -1) {
            return o[1];
        }
        if (o[1] == n) {
            return n - o[0] - 1;
        }
        return (o[1] - o[0]) / 2;
    }

    public ExamRoom(int n) {
        this.n = n;
        this.segmentSet = new TreeSet<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                int d1 = distance(o1);
                int d2 = distance(o2);
                if (d1 == d2) {
                    return Integer.compare(o1[0], o2[0]);
                }
                return Integer.compare(d2, d1);
            }
        });
        this.leftMap = new HashMap<>();
        this.rightMap = new HashMap<>();
        insert(new int[]{-1, n});
    }

    private void insert(int[] o) {
        segmentSet.add(o);
        leftMap.put(o[1], o[0]);
        rightMap.put(o[0], o[1]);
    }

    private void remove(int[] o) {
        segmentSet.remove(o);
        int left = leftMap.remove(o[1]);
        int right = rightMap.remove(o[0]);
    }

    public int seat() {
        int[] first = segmentSet.pollFirst();
        int x = first[0], y = first[1], seat = (y + x) / 2;
        if (x == -1) {
            seat = 0;
        } else if (y == n) {
            seat = n - 1;
        }
        remove(first);
        insert(new int[]{x, seat});
        insert(new int[]{seat, y});
        return seat;
    }

    public void leave(int p) {
        int left = leftMap.get(p);
        int right = rightMap.get(p);
        remove(new int[]{left, p});
        remove(new int[]{p, right});
        insert(new int[]{left, right});
    }
}

/**
 * Your ExamRoom object will be instantiated and called as such:
 * ExamRoom obj = new ExamRoom(n);
 * int param_1 = obj.seat();
 * obj.leave(p);
 */
posted @ 2022-02-08 15:44  Tianyiya  阅读(37)  评论(0)    收藏  举报