不开心的小朋友
题目描述:
游乐场里增加了一批摇摇车,非常受小朋友欢迎,但是每辆摇摇车同时只能有一个小朋友使用,如果没有空余的摇摇车需要排队等候,或者直接离开,最后没有玩上的小朋友会非常不开心。
请根据今天小朋友的来去情况,统计不开心的小朋友数量
1.摇摇车数量为N,范围是: 1 <= N < 10;
2.每个小朋友都对应一个编码,编码是不重复的数字,今天小朋友的来去情况,可以使用编码表示为:1 1 2 3 2 3。(若小朋友离去之前有空闲的摇摇车,则代表玩耍后离开;不考虑小朋友多次玩的情况)。小朋友数量≤ 100
3.题目保证所有输入数据无异常且范围满足上述说明
输入输出描述:
输入描述:
第一行: 摇摇车数量
第二行: 小朋友来去情况
输出描述:
返回不开心的小朋友数量
示例1:
输入:
1
1 2 1 2
输出:
0
说明:
第一行,1个摇摇车
第二行,1号来 2号来(排队)
第三行,1号走 2号走(1号走后摇摇车已有空闲,所以玩后离开)
示例2:
输入:
1
1 2 2 3 1 3
输出:
1
说明:
第一行,1个摇摇车
第二行,1号来 2号来(排队) 2号走(不开心离开) 3号来(排队) 1号走 3号走(1号走后摇摇车已有空闲,所以玩后离)
示例3:
输入:
3
1 2 3 4 5 6 7 3 8 2 1 6 8 7 5 4
输出:
1
说明:
第一行,3个摇摇车
最终只有8号没有坐过车
解题思路:
如下图(先看图,理解最后分析过程)所示,是示例3的过程分析,由此可以得出解决问题的思路如下:
1、使用一个数来记录空闲小车的数量;使用一个Set来记录小朋友出现的历史记录(方便判断小朋友是第一次出现还是第二次,如果是第二次则说明他是要离开了);使用两个结构(Set、List)来记录等待的小朋友,Set是为了在小朋友离开的时候,快速判断其是否还在等待队列中,而List则就是为了某个记录小朋友是第几个等待者。
2、模拟小朋友的来去情况:
①若小朋友第一次出现,则判断是否有空闲的小车
A、有则他坐车,同时空闲小车数量 -1;
B、没有则将其放入等待队列中。
②若小朋友第二次出现,判断其是否在等待队列中,
A、是则表明其没有坐车就离开;
B、若小朋友不在等待队列中,说明其在小车上,他走空出一个车,若还有小朋友在等待,则从等待队列中找出最早来的那个小朋友上车
代码:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int cars = Integer.parseInt(scanner.nextLine());
String[] split = scanner.nextLine().split(" ");
int n = split.length;
// 记录小朋友是否出现过,即用于判断小朋友是要等车还是离开
Set<Integer> history = new HashSet<>();
// 记录等待的小朋友
Set<Integer> waitId = new HashSet<>();
// 记录等待的小朋友是第几个等待者,因为坐车是按照先来先坐的次序
List<int[]> wait = new ArrayList<>();
int res = 0;
// 记录等待的小朋友是第几个等待者
int waitIndex = 0;
for (int i = 0; i < n; i++) {
int curChild = Integer.parseInt(split[i]);
// 小朋友之前出现过——出现过代表小朋友离开
if (history.contains(curChild)) {
// 判断小朋友有没有做过车
if (waitId.contains(curChild)) {
// 小朋友在等待队列中
res++;
// 把小朋友从等待队列中删除
waitId.remove(curChild);
int removeIndex = 0;
for (int j = 0; j < wait.size(); j++) {
if (wait.get(j)[1] == curChild) {
removeIndex = j;
break;
}
}
wait.remove(removeIndex);
} else {
// 小朋友坐过车
// 如果还有小朋友,则让下一位小朋友过来坐车
if (waitId.size() > 0) {
Collections.sort(wait, (a, b)->a[1] - b[1]);
int[] first = wait.remove(0);
waitId.remove(first[1]);
} else {
cars++;
}
history.remove(curChild);
}
} else {
history.add(curChild);
// 看是否有空余的玩具车
if (cars > 0) {
cars--;
} else {
// 进入队列等待
waitId.add(curChild);
// waitIndex一直在增加,是为了防止在中途的时候,等待队列中某个小朋友离开,会导致等待队列乱序
wait.add(new int[] {waitIndex++, curChild});
}
}
}
System.out.println(res);
}