LeetCode-汽车碰撞次数
今天刷一道有意思的题目,逻辑很简单,有点像消消乐。就是当车发生碰撞时,车辆就是会静止,最后所有车辆都因为碰撞而会静止,题目如下
在一条无限长的公路上有 n 辆汽车正在行驶。汽车按从左到右的顺序按从 0 到 n - 1 编号,每辆车都在一个 独特的 位置。给你一个下标从 0 开始的字符串 directions ,长度为 n 。directions[i] 可以是 'L'、'R' 或 'S' 分别表示第 i 辆车是向 左 、向 右 或者 停留 在当前位置。每辆车移动时 速度相同 。
碰撞次数可以按下述方式计算:
-
当两辆移动方向 相反 的车相撞时,碰撞次数加 2 。
-
当一辆移动的车和一辆静止的车相撞时,碰撞次数加 1 。
-
碰撞发生后,涉及的车辆将无法继续移动并停留在碰撞位置。除此之外,汽车不能改变它们的状态或移动方向。
返回在这条道路上发生的 碰撞总次数 。
示例 1:
输入:directions = "RLRSLL"
输出:5
解释:
将会在道路上发生的碰撞列出如下:
- 车 0 和车 1 会互相碰撞。由于它们按相反方向移动,碰撞数量变为 0 + 2 = 2 。
- 车 2 和车 3 会互相碰撞。由于 3 是静止的,碰撞数量变为 2 + 1 = 3 。
- 车 3 和车 4 会互相碰撞。由于 3 是静止的,碰撞数量变为 3 + 1 = 4 。
- 车 4 和车 5 会互相碰撞。在车 4 和车 3 碰撞之后,车 4 会待在碰撞位置,接着和车 5 碰撞。碰撞数量变为 4 + 1 = 5 。
因此,将会在道路上发生的碰撞总次数是 5 。
示例 2:
输入:directions = "LLRR"
输出:0
解释:
不存在会发生碰撞的车辆。因此,将会在道路上发生的碰撞总次数是 0 。
示例 3:
输入:directions = "RRRLL"
输出:6
解释:
将会在道路上发生的碰撞列出如下:
- 车 0 ,车 1和车 2 都不会互相碰撞。因为它们按相同方向移动,碰撞次数是 0。
- 车 2 和车 3 会互相碰撞。由于它们按相反方向移动,碰撞数量变为 0 + 2 = 2 。
- 由于车 2和车 3发生了碰撞,此时道路上的车是这个状态 "RRSSL"
- 车 1和车 2 发生碰撞,由于车2是静止状态,碰撞数量变为 2 + 1 =3
- 车 0和车 1 发生碰撞,由于车1是静止状态,碰撞数量变为 3 + 1 =4
- 车 3和车 4 发生碰撞,由于车1是静止状态,碰撞数量变为 4 + 1 =5
因此,将会在道路上发生的碰撞总次数是 5 。
算法思路
看到这个过程,我的第一想法是用栈,把前面的车的状态推入到栈顶,每来下一辆车,就判断是否会相撞,如果不会相撞就继续压入栈顶,如果会相撞就把两辆车的状态变为 S 再压入栈,如此往复。车辆会相撞的情况就三种:RL,RS,SL。最后代码实现如下
class Solution {
public int countCollisions(String directions) {
if(directions.length()<2){
return 0;
}
LinkedList<Character> queue = new LinkedList<>();
queue.push(directions.charAt(0));
int res=0;
for(int i=1;i<directions.length();i++){
char ch=queue.pop();
char now=directions.charAt(i);
while (true){
int count = pick(ch,now);
res=res+count;
if(count==0){
queue.push(ch);
queue.push(now);
break;
}else {
now='S';
}
if(queue.isEmpty()){
queue.push('S');
break;
}
ch=queue.pop();
}
}
return res;
}
private int pick(char old, char now){
if(old=='R'&&now=='L'){
return 2;
}
if(old=='R'&&now=='S'){
return 1;
}
if(old=='S'&&now=='L'){
return 1;
}
return 0;
}
}