You are given two integer arrays: students
and sandwiches
, both of the same length. Each element in students
represents a student's sandwich preference: 0
for circular and 1
for square. The sandwiches
array represents a stack of sandwiches in order, where the first element is at the top of the stack.
The serving process is as follows:
Key constraints:
At first glance, the problem seems to suggest simulating the entire process: moving students to the back of the queue if they can't eat, and removing sandwiches as they are taken. This would involve repeatedly rotating the queue and checking preferences, which could be inefficient for large inputs.
However, upon closer inspection, we notice that if no one in the queue wants the top sandwich, the process must stop, and all remaining students are unable to eat. Thus, we only need to keep track of the students' preferences and match them to the sandwiches in order, stopping as soon as a sandwich is encountered that no student wants.
This insight allows us to shift from a brute-force simulation to a more efficient approach, where we simply count preferences and compare them to the sandwiches in order.
We can solve the problem efficiently by following these steps:
0
) and square (1
) sandwiches.sandwiches
stack from top to bottom:
This approach avoids unnecessary rotations and checks, leading to a much more efficient solution.
Let's consider an example:
Input:
students = [1,1,0,0]
sandwiches = [0,1,0,1]
Step-by-step process:
0
): 21
): 20
(circular): There are 2 students who want it. Serve one, decrement count to 1.1
(square): There are 2 students who want it. Serve one, decrement count to 1.0
(circular): 1 student left who wants it. Serve, decrement count to 0.1
(square): 1 student left who wants it. Serve, decrement count to 0.If at any point there are no students left who want the current sandwich, the process stops and the remaining students are counted as unable to eat.
Brute-force approach:
The key insight is recognizing that once no student wants the top sandwich, the process must stop. By counting student preferences and matching them directly to the sandwich stack, we avoid unnecessary simulation and achieve an efficient O(n) solution. This approach is both elegant and practical, especially for large inputs.
class Solution:
def countStudents(self, students, sandwiches):
from collections import Counter
pref = Counter(students)
for s in sandwiches:
if pref[s] == 0:
return pref[0] + pref[1]
pref[s] -= 1
return 0
class Solution {
public:
int countStudents(vector<int>& students, vector<int>& sandwiches) {
int count[2] = {0, 0};
for (int s : students) count[s]++;
for (int s : sandwiches) {
if (count[s] == 0)
return count[0] + count[1];
count[s]--;
}
return 0;
}
};
class Solution {
public int countStudents(int[] students, int[] sandwiches) {
int[] count = new int[2];
for (int s : students) count[s]++;
for (int s : sandwiches) {
if (count[s] == 0)
return count[0] + count[1];
count[s]--;
}
return 0;
}
}
var countStudents = function(students, sandwiches) {
let count = [0, 0];
for (let s of students) count[s]++;
for (let s of sandwiches) {
if (count[s] === 0)
return count[0] + count[1];
count[s]--;
}
return 0;
};