DEV Community

Wenqi Jiang
Wenqi Jiang

Posted on • Updated on

[Binary Search]Revolving Door

Revolving Door

You are given a list of list of integers requests. requests[i] contains [time, direction] meaning at time time, a person arrived at the door and either wanted to go in (1) or go out (0).

Given that there's only one door and it takes one time unit to use the door, we have the following rules to resolve conflicts:

  • The door starts with in position and then is set to the position used by the last person.
  • If there's only one person at the door at given time, they can use the door.
  • When two or more people want to go in, earliest person goes first and then the direction previously used holds precedence.
  • If no one uses the door for one time unit, it reverts back to the starting in position.

Return a sorted list of lists where each element contains [time, direction], meaning at time, a person either went in or out.

Constraints

0 ≤ n ≤ 100,000 where n is the length of requests

Example 1

Input

requests = [
    [1, 0],
    [2, 1],
    [5, 0],
    [5, 1],
    [2, 0]
]
Enter fullscreen mode Exit fullscreen mode

Output

[
    [1, 0],
    [2, 0],
    [3, 1],
    [5, 1],
    [6, 0]
]
Enter fullscreen mode Exit fullscreen mode

Explanation

The door starts as in

At time 1, there's only one person so they can go out. Door becomes out.
At time 2, there's two people but the person going out has priority so they go out.
At time 3, the person looking to go in can now go in.
At time 5, there's two people but the person going in has priority so they go out.
At time 6, the last person can go out.

Example 2

Input

requests = [
    [1, 0],
    [2, 0],
    [2, 1],
    [1, 1]
]
Enter fullscreen mode Exit fullscreen mode

Output

[
    [1, 1],
    [2, 0],
    [3, 0],
    [4, 1]
]
Enter fullscreen mode Exit fullscreen mode

Explanation

The door starts as in

At time 1, there's two people but the person going in has higher priority.
At time 2, the other person who came at time 1 can go out. Door becomes out
At time 3, there's two people but the person going out has higher priority.
At time 4, the last person can go in


Intuition

  1. build a time table;
  2. do operations
    • if door is in, let people who want to come in go firstly ,and then, change door to another way, let people who want come out
    • take care of time sequence and door state (because it changes to in after over one unit time without and operation)

Implementation

time table

       for (int[] request : requests) {
            int time = request[0];
            LinkedList<Integer> operations = timeTable.getOrDefault(time, new LinkedList<>());
            operations.addLast(request[1]);
            timeTable.put(time, operations);
        }
Enter fullscreen mode Exit fullscreen mode

change door after one unit time without any operation

            if (time - lastTime >= 1) {
                lastOperation = 1;
            }
Enter fullscreen mode Exit fullscreen mode

Time Complexity

O(n): you need to loop whole requests

Space Complexity

O(n): need to store time table and answer

Solution

import java.util.*;

class Solution {
    public int[][] solve(int[][] requests) {
        int[][] ans = new int[requests.length][2];
        int index = 0;
        int lastTime = -1;
        int lastOperation = 1;

        TreeMap<Integer, LinkedList<Integer>> timeTable = new TreeMap<>();
        for (int[] request : requests) {
            int time = request[0];
            LinkedList<Integer> operations = timeTable.getOrDefault(time, new LinkedList<>());
            operations.addLast(request[1]);
            timeTable.put(time, operations);
        }

        for (int time : timeTable.keySet()) {
            if (time - lastTime >= 1) {
                lastOperation = 1;
            }
            LinkedList<Integer> operations = timeTable.get(time);
            int operationTime = index == 0 ? time : Math.max(time, ans[index - 1][0] + 1);
            while (operations.size() > 0) {
                if (operations.contains(lastOperation)) {
                    ans[index][0] = operationTime++;
                    ans[index][1] = lastOperation;
                    lastTime = operationTime;
                    index++;
                    operations.removeFirstOccurrence(lastOperation);
                } else {
                    lastOperation = lastOperation == 1 ? 0 : 1;
                }
            }
        }
        return ans;
    }
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)