题目描述:
学校的自助午餐提供圆形和方形的三明治,分别用数字 0 和 1 表示。所有学生站在一个队列里,每个学生要么喜欢圆形的要么喜欢方形的。
餐厅里三明治的数量与学生的数量相同。所有三明治都放在一个 栈 里,每一轮:
如果队列最前面的学生 喜欢 栈顶的三明治,那么会 拿走它 并离开队列。
否则,这名学生会 放弃这个三明治 并回到队列的尾部。
这个过程会一直持续到队列里所有学生都不喜欢栈顶的三明治为止。
给你两个整数数组 students 和 sandwiches ,其中 sandwiches[i] 是栈里面第 i 个三明治的类型(i = 0 是栈的顶部), students[j] 是初始队列里第 j 名学生对三明治的喜好(j = 0 是队列的最开始位置)。请你返回无法吃午餐的学生数量。
解题思路:
我们可以发现我们实质是每次遍历(以三明治栈顶元素为标准)比较三明治栈顶元素和学生队尾的元素是否相等,再进行接下来的操作。但是我们应该进一步明确不论学生队列如何移动都是要看学生队列目前剩下的是否存在和当前三明治栈顶元素相匹配的元素(更抽象的说就是和学生队列的顺序无关和当前存在的相匹配的个数有关),在明确该点后我们可以进行如下操作:
1.统计学生队列中分别喜欢圆形和三角形三明治的学生人数
2.遍历三明治栈,同时分别判断学生队列中对应的学生人数是否还大于0,若大于0则喜欢对应三明治的人数减一;若已经存在等于0则中断遍历
3最后返回最后剩下的喜欢圆形和方形三明治的人数的总和即为吃不上的人数。
代码:
class Solution {
// Time Complexity: O(N)
// Space Complexity: O(1)
public int countStudents(int[] students, int[] sandwiches) {
// 统计喜欢不同三明治的人数
int countSquare = Arrays.stream(students).sum();
int countCircle = students.length - countSquare;
for (int i = 0; i < sandwiches.length; i++) {
if (sandwiches[i] == 1 && countSquare > 0) {
countSquare--;
} else if (sandwiches[i] == 0 && countCircle > 0) {
countCircle--;
} else {
break;
}
}
return countCircle + countSquare;
}
}