[Binary Search]Revolving Door
Tags: algorithms, java
Published: 2021-11-23 17:35:46

[Revolving Door](https://binarysearch.com/problems/Revolving-Door/solutions/6910020)


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]
]
```

## Output
```
[
    [1, 0],
    [2, 0],
    [3, 1],
    [5, 1],
    [6, 0]
]
```

## 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]
]
```
## Output
```
[
    [1, 1],
    [2, 0],
    [3, 0],
    [4, 1]
]
```

## 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

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

### change door after one unit time without any operation

```java
            if (time - lastTime >= 1) {
                lastOperation = 1;
            }
```

### Time Complexity
O(n): you need to loop whole requests

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



# Solution

```java
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;
    }
}

```