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
lengthto the length ofstudents.
Thesandwicheshave the same length as thestudents.
Initializestudent_queuewith an empty deque.
Actually, you can initializestudent_queuewithstudents, but it will require one more loop for initialization.
Initializesandwich_stackwith an empty list. - Iterate from 0 to
length:- Append
students[i]intostudent_queue(Convert thestudentslist to a deque). - Append
sandwiches[length - 1 - i]intosandwich_stack(Reverse thesandwicheslist).
- Append
- Initialize
last_servedto 0.
We'll uselast_servedto check if we have checked around thestudent_queue. - Iterate through the
sandwich_stackwhilelast_servedis smaller than the length ofstudent_queue:current_studentis the student dequeued from the left ofstudent_queue.- If the top sandwich from
sandwich_stackis equals tocurrent_student:- Pop the top sandwich from
sandwich_stack. - Reset
last_servedto 0.
- Pop the top sandwich from
- Otherwise, append
current_studentback tostudent_queue- Increase
last_servedby 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_counterto zero andsquare_counterto zero. - Iterate through
students:- If the student is 0, increase
circular_counterby 1. - If the student is 1, increase
square_counterby 1.
- If the student is 0, increase
- Iterate through
sandwiches:- If the sandwich is 0 and
circular_counteris not zero:- Decrease
circular_counterby1.
- Decrease
- If the sandwich is 1 and
square_counteris not zero:- Decrease
square_counterby1.
- Decrease
- Otherwise, the current sandwich cannot provide to any student:
- Return
circular_counterplussquare_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.