1700. Number of Students Unable to Eat Lunch
Overview
The question has a long description, but the situation is quite simple.
The restaurant will provide two kinds of sandwiches: circular sandwiches (0) and square sandwiches (1).
And students have their own preferences with the sandwiches.
We can only provide the top sandwich to the students.
When the student get their preferred sandwich, they will leave the line.
Otherwise, they will go to the back of the line.
We need to find out how many students cannot be provided.
Solution 1: Queue and Stack
Thinking
We just use code to simulate the situation.
Students are like deque. They will go out from the left and go in from the right.
Sandwiches are like stack. They will go out from the top.
Algorithm
- Initialize
length
to the length ofstudents
.
Thesandwiches
have the same length as thestudents
.
Initializestudent_queue
with an empty deque.
Actually, you can initializestudent_queue
withstudents
, but it will require one more loop for initialization.
Initializesandwich_stack
with an empty list. - Iterate from 0 to
length
:- Append
students[i]
intostudent_queue
(Convert thestudents
list to a deque). - Append
sandwiches[length - 1 - i]
intosandwich_stack
(Reverse thesandwiches
list).
- Append
- Initialize
last_served
to 0.
We'll uselast_served
to check if we have checked around thestudent_queue
. - Iterate through the
sandwich_stack
whilelast_served
is smaller than the length ofstudent_queue
:current_student
is the student dequeued from the left ofstudent_queue
.- If the top sandwich from
sandwich_stack
is equals tocurrent_student
:- Pop the top sandwich from
sandwich_stack
. - Reset
last_served
to 0.
- Pop the top sandwich from
- Otherwise, append
current_student
back tostudent_queue
- Increase
last_served
by 1.
- Increase
- Return the length of
student_queue
, which represents the number of students who didn't get sandwiches.
Implement
class Solution: def countStudents(self, students: list[int], sandwiches: list[int]) -> int: length = len(students) student_queue: deque[int] = deque() sandwich_stack: list[int] = [] for i in range(length): student_queue.append(students[i]) sandwich_stack.append(sandwiches[length - 1 - i]) last_served = 0 while sandwich_stack and last_served < len(student_queue): current_student = student_queue.popleft() if sandwich_stack[-1] == current_student: sandwich_stack.pop() last_served = 0 else: student_queue.append(current_student) last_served += 1 return len(student_queue)
Complexity Analysis
Time complexity: O(n)
Iterating from 0 to length
takes O(n) time.
Iterating through the sandwich_stack
takes O(n) time in the worst case.
The total time complexity is O(2n), which simplifies to O(n).
Space complexity: O(n + m)
We use an additional deque and an additional stack, which takes O(n + m) space.
Solution 2: Counter
Algorithm
- Initialize
circular_counter
to zero andsquare_counter
to zero. - Iterate through
students
:- If the student is 0, increase
circular_counter
by 1. - If the student is 1, increase
square_counter
by 1.
- If the student is 0, increase
- Iterate through
sandwiches
:- If the sandwich is 0 and
circular_counter
is not zero:- Decrease
circular_counter
by1.
- Decrease
- If the sandwich is 1 and
square_counter
is not zero:- Decrease
square_counter
by1.
- Decrease
- Otherwise, the current sandwich cannot provide to any student:
- Return
circular_counter
plussquare_counter
, representing the number of the students who didn't get the sandwich.
- Return
- If the sandwich is 0 and
- Return 0 that all the students have been served.
Implement
class Solution: def countStudents(self, students: list[int], sandwiches: list[int]) -> int: circular_counter = 0 square_counter = 0 for student in students: if student == 0: circular_counter += 1 else: # 1 square_counter += 1 for sandwich in sandwiches: if sandwich == 0 and circular_counter: circular_counter -= 1 elif sandwich == 1 and square_counter: square_counter -= 1 else: return circular_counter + square_counter return 0
Complexity Analysis
Time complexity: O(n)
Iterating through the students
takes O(n) time.
Iterating through the sandwiches
also takes O(n) time.
The total time complexity is O(2n), which simplifies to O(n).
Space complexity: O(1)
We use two additional variables which takes constant space.