Java || Detail explanation of the solution || Better variable names || TC & SC explained
// TC : Adding/Removing from TreeSet takes O(logN) times\n// SC : O(N)\n\nclass ExamRoom {\n\n    TreeSet<Integer> seatTakenAtI; // TreeSet because of lower() a
// TC : Adding/Removing from TreeSet takes O(logN) times\n// SC : O(N)\n```\nclass ExamRoom {\n\n    TreeSet<Integer> seatTakenAtI; // TreeSet because of lower() and higher() methods\n    TreeSet<Intervals> nextIntervalToFill; // Priority Queue could also be used here with custom Comparator (removing any obj other than min/max takes O(N) times in PQ)\n    int max;\n    \n    public ExamRoom(int n) {\n        seatTakenAtI = new TreeSet<>();\n        nextIntervalToFill = new TreeSet<>((a,b) -> b.intervalSize != a.intervalSize ? b.intervalSize - a.intervalSize : a.leftOfInterval - b.leftOfInterval); // look at the rules (2 & 3) explained before seat() method below\n        max = n;\n        \n        // We need a default interval (the whole space) to make students sit\n        nextIntervalToFill.add(new Intervals(-1, max, n));\n    }\n    \n    // There are following rules to make student sit at particular place:\n    // 1. If no one is there, then sit at 0\n    // 2. Maximize the distance between 2 students, so fill LARGER interval first\n    // 3. If the Intervals (to be filled next) have same size, then make student sit at lower seat number, basically the interval at left side of scale\n    public int seat() {\n        int pos = 0; // default\n        \n        Intervals interval = nextIntervalToFill.pollFirst(); // always poll the interval on top (it is on the top because of the rules defined above)\n        \n        // create the new interval(s) depending on the position\n        if(interval.leftOfInterval == -1) { // if there is no student in the class\n            pos = 0;\n            nextIntervalToFill.add(new Intervals(pos, interval.rightOfInterval, max)); // add the remaining interval to the SET\n        } else if(interval.rightOfInterval == max) { // when there is only 1 student (on seat 0)\n            pos = max - 1;\n            nextIntervalToFill.add(new Intervals(interval.leftOfInterval, pos, max));\n        } else {\n            pos = interval.leftOfInterval + (interval.rightOfInterval - interval.leftOfInterval)/2; // mid seat of the top interval in the SET (to maximize the dist)\n            // since the new student will be added to this seat which is at MID of previous interval, it will create 2 new intervals and we need to add them in our SET\n            nextIntervalToFill.add(new Intervals(interval.leftOfInterval, pos, max));\n            nextIntervalToFill.add(new Intervals(pos, interval.rightOfInterval, max));\n        }\n        \n        // always fill the seat at \'pos\'\n        seatTakenAtI.add(pos);\n        return pos;\n    }\n    \n    // when a student is removed from a \'pos\', 2 things happen\n    // 1. the 2 intervals to the left and right of this \'pos\' does not remain valid (since the divding factor \'pos\' is no more there)\n    // 2. a new interval (composed of the above 2 intervals at left and right of \'pos\') is formed\n    // So remove the 2 intervals from the SET and add the newer one\n    public void leave(int p) {\n        int startIdxOfLeftInterval = seatTakenAtI.lower(p) == null ? -1 : seatTakenAtI.lower(p); // the \'p\' could be 0 otherwise lower(p) returns GREATEST ele in SET which is STRICTLY less than \'p\'\n        int endIdxOfRightInterval  = seatTakenAtI.higher(p) == null ? max : seatTakenAtI.higher(p); // the \'p\' could be N otherise higher(p) returns LEAST ele in SET which is STRICTLT greater than \'p\'\n        \n        // create the 2 intervals at left and right of \'p\' and remove them\n        Intervals leftInterval = new Intervals(startIdxOfLeftInterval, p, max);\n        Intervals rightInterval = new Intervals(p , endIdxOfRightInterval, max);\n        nextIntervalToFill.remove(leftInterval);\n        nextIntervalToFill.remove(rightInterval);\n        \n        // create new interval and add it to SET\n        Intervals newInterval = new Intervals(startIdxOfLeftInterval, endIdxOfRightInterval, max);\n        nextIntervalToFill.add(newInterval);\n        \n        // dont forget to remove the student from \'p\'\n        seatTakenAtI.remove(p);\n    }\n}\n\n// Basic class to mark interval\'s size, left idx and right idx\nclass Intervals {\n    int leftOfInterval;\n    int rightOfInterval;\n    int intervalSize;\n    \n    public Intervals(int x, int y, int n) {\n        this.leftOfInterval = x;\n        this.rightOfInterval = y;\n        \n        if(x == -1) {\n            this.intervalSize = y;\n        } else if(y == n) {\n            this.intervalSize = n - 1 - x;\n        } else {\n            this.intervalSize = Math.abs(x - y)/2; // /2 to handle middle point issue (in case the left and right interval differ by just 1 and if putting the cstudent even in higher sized interval is same as in lower side interval, so we should prefer lower side); use the example to layout the numbers and you will see the reason\n        }\n    }\n}\n```
[]