3168. Minimum Number of Chairs in a Waiting Room
Problem Description
You are given a string s
that represents events happening at each second in a waiting room. Each character in the string represents what happens at that second:
- If
s[i] == 'E'
: A person enters the waiting room and takes one of the chairs - If
s[i] == 'L'
: A person leaves the waiting room and frees up a chair
The waiting room starts empty with no chairs initially. Your task is to find the minimum number of chairs needed so that every person who enters the waiting room can have a chair to sit on.
For example, if s = "EELLL"
:
- At second 0: Person enters, need 1 chair (total chairs needed: 1)
- At second 1: Another person enters, need 1 more chair (total chairs needed: 2)
- At second 2: Person leaves, 1 chair becomes free
- At second 3: Person leaves, 2 chairs are now free
- At second 4: Person leaves (but only 2 people entered, so this represents an already empty chair)
The key insight is that we need to track the maximum number of people in the room at any given time, which determines the minimum chairs required.
Intuition
The key observation is that we need to track two things: the total number of chairs we've acquired so far, and how many of those chairs are currently empty (available for reuse).
Think of it this way - when someone enters ('E'
), they need a chair. If there's an empty chair available from someone who left earlier, we can reuse it. If not, we need to get a new chair. Once we get a chair, it stays in the waiting room forever - we never remove chairs, we just track whether they're occupied or empty.
When someone leaves ('L'
), they free up a chair that can be reused by the next person who enters.
This leads us to a greedy approach:
- Keep a counter
cnt
for the total number of chairs we've acquired - Keep a counter
left
for the number of currently empty chairs - When we see
'E'
:- If
left > 0
, someone can use an empty chair (decreaseleft
by 1) - If
left == 0
, all chairs are occupied, so we need a new chair (increasecnt
by 1)
- If
- When we see
'L'
:- A chair becomes empty (increase
left
by 1)
- A chair becomes empty (increase
The beauty of this approach is that we only add new chairs when absolutely necessary - when someone enters and all existing chairs are occupied. This naturally gives us the minimum number of chairs needed.
Solution Approach
We implement a simulation approach that processes each event in the string sequentially:
Variables Used:
cnt
: Tracks the total number of chairs we've acquired (this is our answer)left
: Tracks the number of currently empty/available chairs
Algorithm Steps:
-
Initialize both
cnt
andleft
to 0, since the waiting room starts empty with no chairs. -
Iterate through each character
c
in the strings
:When
c == 'E'
(person enters):- Check if there are any empty chairs available (
left > 0
) - If yes: Use one empty chair by decrementing
left
by 1 - If no: All existing chairs are occupied, so we need to add a new chair by incrementing
cnt
by 1
When
c == 'L'
(person leaves):- The person frees up their chair, so increment
left
by 1
- Check if there are any empty chairs available (
-
After processing all events, return
cnt
as the minimum number of chairs needed.
Example Walkthrough:
For s = "EELEE"
:
- i=0, 'E':
left=0
, so add new chair →cnt=1, left=0
- i=1, 'E':
left=0
, so add new chair →cnt=2, left=0
- i=2, 'L': person leaves →
cnt=2, left=1
- i=3, 'E':
left=1
, use empty chair →cnt=2, left=0
- i=4, 'E':
left=0
, so add new chair →cnt=3, left=0
Final answer: 3 chairs needed
The time complexity is O(n)
where n
is the length of the string, and space complexity is O(1)
as we only use two variables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the example s = "EELEELL"
to understand how our solution works:
Initial State:
cnt = 0
(no chairs acquired yet)left = 0
(no empty chairs available)
Processing each second:
Second 0: 'E' (person enters)
- Check: Are there empty chairs?
left = 0
, so NO - Action: Need a new chair, so
cnt = 1
- State:
cnt = 1, left = 0
Second 1: 'E' (person enters)
- Check: Are there empty chairs?
left = 0
, so NO - Action: Need another new chair, so
cnt = 2
- State:
cnt = 2, left = 0
Second 2: 'L' (person leaves)
- Action: A chair becomes empty, so
left = 1
- State:
cnt = 2, left = 1
Second 3: 'E' (person enters)
- Check: Are there empty chairs?
left = 1
, so YES - Action: Use the empty chair, so
left = 0
- State:
cnt = 2, left = 0
Second 4: 'E' (person enters)
- Check: Are there empty chairs?
left = 0
, so NO - Action: Need a new chair, so
cnt = 3
- State:
cnt = 3, left = 0
Second 5: 'L' (person leaves)
- Action: A chair becomes empty, so
left = 1
- State:
cnt = 3, left = 1
Second 6: 'L' (person leaves)
- Action: Another chair becomes empty, so
left = 2
- State:
cnt = 3, left = 2
Final Answer: 3 chairs
The key insight: We only added new chairs (increased cnt
) when someone entered and all existing chairs were occupied. When chairs became available from people leaving, we reused them instead of adding more chairs. This greedy approach ensures we use the minimum number of chairs possible.
Solution Implementation
1class Solution:
2 def minimumChairs(self, s: str) -> int:
3 # Track the total number of chairs needed
4 chairs_needed = 0
5
6 # Track the number of available (empty) chairs
7 available_chairs = 0
8
9 # Process each event in the string
10 for event in s:
11 if event == "E": # Person entering
12 if available_chairs > 0:
13 # Use an available chair
14 available_chairs -= 1
15 else:
16 # No available chairs, need to add a new one
17 chairs_needed += 1
18 else: # Person leaving (event == "L")
19 # Chair becomes available
20 available_chairs += 1
21
22 return chairs_needed
23
1class Solution {
2 public int minimumChairs(String s) {
3 // Track the total number of chairs needed
4 int totalChairsNeeded = 0;
5
6 // Track the number of currently available (empty) chairs
7 int availableChairs = 0;
8
9 // Process each character in the string
10 for (int i = 0; i < s.length(); i++) {
11 char currentEvent = s.charAt(i);
12
13 if (currentEvent == 'E') {
14 // Person entering the room
15 if (availableChairs > 0) {
16 // Use an existing available chair
17 availableChairs--;
18 } else {
19 // No available chairs, need to add a new one
20 totalChairsNeeded++;
21 }
22 } else {
23 // Person leaving the room (assumes 'L')
24 // Their chair becomes available
25 availableChairs++;
26 }
27 }
28
29 return totalChairsNeeded;
30 }
31}
32
1class Solution {
2public:
3 int minimumChairs(string s) {
4 int totalChairsNeeded = 0; // Total number of chairs required
5 int availableChairs = 0; // Number of currently available (empty) chairs
6
7 // Iterate through each event in the string
8 for (char& event : s) {
9 if (event == 'E') { // Person enters the room
10 if (availableChairs > 0) {
11 // Use an available chair
12 --availableChairs;
13 } else {
14 // No available chairs, need to add a new one
15 ++totalChairsNeeded;
16 }
17 } else { // event == 'L', person leaves the room
18 // One more chair becomes available
19 ++availableChairs;
20 }
21 }
22
23 return totalChairsNeeded;
24 }
25};
26
1/**
2 * Calculates the minimum number of chairs needed for a waiting room
3 * @param s - String of 'E' (enter) and 'L' (leave) events
4 * @returns The minimum number of chairs required
5 */
6function minimumChairs(s: string): number {
7 // Track the total chairs needed and available chairs
8 let totalChairsNeeded: number = 0;
9 let availableChairs: number = 0;
10
11 // Process each event in the string
12 for (const event of s) {
13 if (event === 'E') {
14 // Person enters the waiting room
15 if (availableChairs > 0) {
16 // Use an available chair
17 availableChairs--;
18 } else {
19 // Need a new chair
20 totalChairsNeeded++;
21 }
22 } else {
23 // Person leaves the waiting room (event === 'L')
24 // Their chair becomes available
25 availableChairs++;
26 }
27 }
28
29 return totalChairsNeeded;
30}
31
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the string s
. The algorithm iterates through the string exactly once, performing constant-time operations (O(1)
) for each character - checking if the character is "E" or "L", and updating the counters accordingly.
The space complexity is O(1)
. The algorithm only uses a fixed amount of extra space regardless of the input size, storing just two integer variables: cnt
(to track the minimum chairs needed) and left
(to track available chairs after people leave).
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Tracking Current Occupancy Instead of Total Chairs
The Mistake: Many people initially try to solve this by tracking the current number of people in the room and returning the maximum occupancy:
def minimumChairs(self, s: str) -> int:
current_people = 0
max_people = 0
for event in s:
if event == "E":
current_people += 1
max_people = max(max_people, current_people)
else: # event == "L"
current_people -= 1
return max_people
Why It's Wrong: This approach assumes we can dynamically add and remove chairs as needed. However, once we acquire a chair, we keep it for the entire duration. The problem asks for the minimum number of chairs we need to acquire in total, not the maximum occupancy at any point.
The Fix: Track two separate values:
- Total chairs acquired (which never decreases)
- Available empty chairs (which increases when people leave)
Pitfall 2: Not Handling the Initial Empty State Correctly
The Mistake:
Starting with available_chairs = 1
or some non-zero value, thinking the room has chairs initially:
def minimumChairs(self, s: str) -> int:
chairs_needed = 1 # Wrong: assuming we start with a chair
available_chairs = 1 # Wrong: the room starts empty
# ... rest of code
Why It's Wrong: The problem clearly states "The waiting room starts empty with no chairs initially." We only add chairs when people enter and no empty chairs are available.
The Fix:
Initialize both chairs_needed
and available_chairs
to 0.
Pitfall 3: Misunderstanding What "L" Means
The Mistake: Assuming that "L" always corresponds to a person who previously entered:
def minimumChairs(self, s: str) -> int:
# Trying to validate that leaves match enters
if s.count('L') > s.count('E'):
return -1 # Invalid input
Why It's Wrong: While logically there shouldn't be more leaves than enters in a real scenario, the problem doesn't require us to validate this. We should process the events as given and trust that the input is valid according to the problem constraints.
The Fix: Simply process each 'L' as incrementing available chairs without validation. The problem guarantees valid input sequences.
Which of the following problems can be solved with backtracking (select multiple)
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!