zoukankan      html  css  js  c++  java
  • LeetCode 855. Exam Room

    原题链接在这里:https://leetcode.com/problems/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.

    题解:

    It is clear to find the bigest interval and assign the middle position back.

    Use TreeSet ts to maintain intervals sorted by the distance of interval. At the begining, put a dummy interval into ts.

    When calculating the distance of interval, divide by 2. Because it only puts value to its closest.

    e.g. N = 10. First 3 seats return 0, 9, 4. Now there are 3 seats between [0,4], and 4 seats between [4,9]. 

    But next seat returns 2 in [0,4], but not 6 in [4,9]. Since 2-0 equals to 2, 6-4 still equals to 2.

    And since there are dummy interval, when interval[0] == -1, simple return interval[1]. when interval[1] == N, simple return N-interval[0]-1.

    Also have 2 maps to maintain mapping between startpoint and interval, endpoint and interval.

    For leave(int p), get the left interval with endMap on p. and right interval with startMap on p.

    Merge left and right interval and add merged interval back.

    Time Complexity: seat, O(logn). leave, O(logn). n is count of intervals in ts.

    Space: O(n).

    AC Java: 

     1 class ExamRoom {
     2     int N;
     3     TreeSet<int []> ts;
     4     HashMap<Integer, int []> startMap;
     5     HashMap<Integer, int []> endMap;
     6     
     7     public ExamRoom(int N) {
     8         this.N = N;
     9         ts = new TreeSet<>((a,b) -> {
    10            if(dist(b) == dist(a)){
    11                return a[0] - b[0];
    12            }
    13             
    14            return dist(b) - dist(a);
    15         });
    16         
    17         startMap = new HashMap<>();
    18         endMap = new HashMap<>();
    19         add(new int[]{-1, N});
    20     }
    21     
    22     public int seat() {
    23         int [] top = ts.pollFirst();
    24         
    25         int pos = 0;
    26         if(top[0] == -1){
    27             pos = 0;
    28         }else if(top[1] == N){
    29             pos = N-1;
    30         }else{
    31             pos = top[0] + (top[1]-top[0])/2;
    32         }
    33         
    34         add(new int[]{top[0], pos});
    35         add(new int[]{pos, top[1]});
    36         
    37         return pos;
    38     }
    39     
    40     public void leave(int p) {
    41         int [] left = endMap.get(p);
    42         int [] right = startMap.get(p);
    43         int [] merged = new int[]{left[0], right[1]};
    44         
    45         remove(left);
    46         remove(right);
    47         add(merged);
    48     }
    49     
    50     private int dist(int [] interval){
    51         if(interval[0] == -1){
    52             return interval[1];
    53         }
    54         
    55         if(interval[1] == N){
    56             return N-interval[0]-1;
    57         }
    58         
    59         return (interval[1]-interval[0])/2;
    60     }
    61     
    62     private void add(int [] interval){
    63         ts.add(interval);
    64         startMap.put(interval[0], interval);
    65         endMap.put(interval[1], interval);
    66     }
    67     
    68     private void remove(int [] interval){
    69         ts.remove(interval);
    70         startMap.remove(interval[0]);
    71         endMap.remove(interval[1]);
    72     }
    73 }
    74 
    75 /**
    76  * Your ExamRoom object will be instantiated and called as such:
    77  * ExamRoom obj = new ExamRoom(N);
    78  * int param_1 = obj.seat();
    79  * obj.leave(p);
    80  */
  • 相关阅读:
    并发编程学习笔记(二十九、Unsafe)
    并发编程学习笔记(二十八、ConcurrentHashMap,Java8 ConcurrentHashMap)
    并发编程学习笔记(二十七、ConcurrentHashMap,Java7 ConcurrentHashMap)
    并发编程学习笔记(二十六、ConcurrentHashMap,Java8 HashMap简述)
    位运算符
    并发编程学习笔记(二十五、ConcurrentHashMap,Java7 HashMap简述)
    并发编程学习笔记(二十四、AQS总结)
    并发编程学习笔记(二十三、CopyOnWriteArrayList源码分析)
    我二十多岁了,至今依然一事无成
    从零开始手写 mybatis(一)MVP 版本
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/11857587.html
Copyright © 2011-2022 走看看