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;
    }
}
posted @ 2025-04-04 17:22  街灯以北  阅读(4)  评论(0)    收藏  举报