The school cafeteria offers circular and square sandwiches at lunch break, referred to by numbers 0
and 1
respectively. All students stand in a queue. Each student either prefers square or circular sandwiches.
The number of sandwiches in the cafeteria is equal to the number of students. The sandwiches are placed in a stack. At each step:
This continues until none of the queue students want to take the top sandwich and are thus unable to eat.
You are given two integer arrays students
and sandwiches
where sandwiches[i]
is the type of the ith
sandwich in the stack (i = 0
is the top of the stack) and students[j]
is the preference of the jth
student in the initial queue (j = 0
is the front of the queue). Return the number of students that are unable to eat.
Example 1:
Input: students = [1,1,0,0], sandwiches = [0,1,0,1] Output: 0 Explanation: - Front student leaves the top sandwich and returns to the end of the line making students = [1,0,0,1]. - Front student leaves the top sandwich and returns to the end of the line making students = [0,0,1,1]. - Front student takes the top sandwich and leaves the line making students = [0,1,1] and sandwiches = [1,0,1]. - Front student leaves the top sandwich and returns to the end of the line making students = [1,1,0]. - Front student takes the top sandwich and leaves the line making students = [1,0] and sandwiches = [0,1]. - Front student leaves the top sandwich and returns to the end of the line making students = [0,1]. - Front student takes the top sandwich and leaves the line making students = [1] and sandwiches = [1]. - Front student takes the top sandwich and leaves the line making students = [] and sandwiches = []. Hence all students are able to eat.
Example 2:
Input: students = [1,1,1,0,0,1], sandwiches = [1,0,0,0,1,1] Output: 3
Constraints:
1 <= students.length, sandwiches.length <= 100
students.length == sandwiches.length
sandwiches[i]
is 0
or 1
.students[i]
is 0
or 1
.This problem involves simulating a queue of students and a stack of sandwiches. Students have preferences (0 or 1 representing sandwich type), and they take sandwiches from the stack if they match their preference; otherwise, they go to the back of the queue. The goal is to find how many students are left unable to eat.
The naive approach of simulating the queue and stack directly is possible but inefficient (O(n^2) in the worst case). A much more efficient solution leverages the fact that once a student doesn't get their preferred sandwich, no further sandwiches can be consumed by any student. This is because the process only changes the order of students in the queue, not the sandwich stack.
The optimal solution uses counting to track the number of students with each sandwich preference.
Initialization:
cnt
of size 2) to store the counts of students who prefer sandwich type 0 and sandwich type 1.students
array and incrementing the appropriate count for each student's preference.Iterating Through Sandwiches:
sandwiches
array (representing the stack).v
:
cnt[v]
is 0 (no student wants this type), it means we have reached a point where no more students can eat. The number of students who remain unable to eat is the number of students who prefer the other sandwich type (cnt[v ^ 1]
). We return this value.cnt[v]
because a student has taken this sandwich.All Students Eat:
cnt[v]
is 0, it means all students were able to eat. We return 0.cnt
) to store the counts of student preferences. The space used is independent of the input size.The code examples below implement the optimized counting solution:
Python:
from collections import Counter
class Solution:
def countStudents(self, students: list[int], sandwiches: list[int]) -> int:
cnt = Counter(students) #Efficient counter
for sandwich in sandwiches:
if cnt[sandwich] == 0:
return cnt[1 - sandwich] #Other sandwich type
cnt[sandwich] -= 1
return 0
Java:
class Solution {
public int countStudents(int[] students, int[] sandwiches) {
int[] cnt = new int[2];
for (int student : students) {
cnt[student]++;
}
for (int sandwich : sandwiches) {
if (cnt[sandwich] == 0) {
return cnt[1 - sandwich];
}
cnt[sandwich]--;
}
return 0;
}
}
C++:
class Solution {
public:
int countStudents(vector<int>& students, vector<int>& sandwiches) {
vector<int> cnt(2, 0);
for (int student : students) {
cnt[student]++;
}
for (int sandwich : sandwiches) {
if (cnt[sandwich] == 0) {
return cnt[1 - sandwich];
}
cnt[sandwich]--;
}
return 0;
}
};
JavaScript:
/**
* @param {number[]} students
* @param {number[]} sandwiches
* @return {number}
*/
var countStudents = function(students, sandwiches) {
let cnt = [0, 0];
for (let student of students) {
cnt[student]++;
}
for (let sandwich of sandwiches) {
if (cnt[sandwich] === 0) {
return cnt[1 - sandwich];
}
cnt[sandwich]--;
}
return 0;
};
These code examples are concise and efficient, directly reflecting the optimized counting approach described above. They achieve the optimal time and space complexity.