LeetCode 2211. 统计道路上的碰撞次数

2211. 统计道路上的碰撞次数

在一条无限长的公路上有 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 。

提示:

  • 1 <= directions.length <= 10^5
  • directions[i] 的值为 'L''R' 或 'S'

提示 1

In what circumstances does a moving car not collide with another car?


提示 2

If we disregard the moving cars that do not collide with another car, what does each moving car contribute to the answer?


提示 3

Will stationary cars contribute towards the answer?

解法1:

相撞零次:LR 或 LS 或 SR 或 状态相同 的两辆车。

相撞一次:RS 或 SL。

相撞两次:RL。

去掉往左右两边开的车之后,剩下非停止的车必然会碰撞。

  1. 去除前缀为‘L’的字符;
  2. 去除后缀为‘R’的字符;
  3. 找出剩余字符串中S的个数countS;
  4. 剩下的字符都会贡献一次碰撞次数。
  5. 1个车只能被撞一次

Java版:

字符串后缀匹配‘R’会超时,所以反转后再前缀匹配‘R’。

class Solution {
    public int countCollisions(String directions) {
        directions = directions.replaceAll("^L+", "");
        // directions = directions.replaceAll("R+$", "");
        directions = new StringBuffer(directions).reverse().toString().replaceAll("^R+", "");
        int cnt = 0;
        for (int i = 0; i < directions.length(); i++) {
            if (directions.charAt(i) != 'S') {
                cnt++;
            }
        }
        return cnt;
    }
}

另一种写法:

前置知识:

Java String chars() Method Examples

Java String chars() Method Examples

Java String chars() method returns an IntStream. The stream contains the integer code point values of the characters in the string object. This method was added to the String class in Java 9 release.

Java String chars() Method Examples

Let’s look into some simple examples of chars() method.

1. Printing the String Character Code Points

jshell> String str = "Hello World";
str ==> "Hello World"
 
jshell> str.chars().forEach(System.out::println);
72
101
108
108
111
32
87
111
114
108
100
 
jshell> 

2. Processing String Characters in Parallel

If you have to process the string characters and you don’t mind unordered processing, you can create a parallel stream and process its characters.

jshell> str.chars().parallel().forEach(c -> System.out.println(Character.valueOf((char) c)));
W
o
  
r
l
d
l
o
H
e
l
 
jshell>

3. Converting String to List of Characters

We can use chars() method to get the character stream and process them one at a time. Here is an example to convert a string to list of characters while adding 1 to their code points.

jshell> String str = "Hello World";
str ==> "Hello World"
 
jshell> List<Character> charStr = new ArrayList<>();
charStr ==> []
 
jshell> str.chars().map(x -> x + 1).forEach(y -> charStr.add(Character.valueOf((char) y)));
 
jshell> System.out.println(charStr);
[I, f, m, m, p, !, X, p, s, m, e]
 
jshell> 

Conclusion

Java String chars() method is useful when we have to process the characters of a large string. We can use a parallel stream for faster processing.

 代码实现:

class Solution {
    public int countCollisions(String directions) {
        directions = directions.replaceAll("^L+", "");
        // directions = directions.replaceAll("R+$", "");
        directions = new StringBuffer(directions).reverse().toString().replaceAll("^R+", "");
        
        return (int) directions.chars().filter(c -> c != 'S').count();
    }
}

Python3版:

class Solution:
    def countCollisions(self, directions: str) -> int:
        directions = directions.lstrip('L')
        directions = directions.rstrip('R')
        return len(directions) - directions.count('S')

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串长度。

  • 空间复杂度:O(1).

解法2:栈

相似题型:LeetCode 735. 小行星碰撞-CSDN博客

重点还是要读懂题意:

碰撞发生后,涉及的车辆将无法继续移动并停留在碰撞位置。除此之外,汽车不能改变它们的状态或移动方向。

Java版:

class Solution {
    public int countCollisions(String directions) {
        int cnt = 0;
        ArrayDeque<Character> stack = new ArrayDeque<>();
        for (int i = 0; i < directions.length(); i++) {
            char ch = directions.charAt(i);
            if (stack.isEmpty()) {
                stack.push(ch);
                continue;
            } 
            if (ch == 'L') {
                if (stack.peek() == 'S') {
                    cnt += 1;
                    continue;
                } else if (stack.peek() == 'R') {
                    cnt += 1;
                    while (!stack.isEmpty() && stack.peek() == 'R') {
                        cnt += 1;
                        stack.pop();
                    }
                    stack.push('S');
                } 
            } else if (ch == 'S') {
                while (!stack.isEmpty() && stack.peek() == 'R') {
                    cnt += 1;
                    stack.pop();
                }
                stack.push('S');
            } else {
                stack.push('R');
            }
        }
        return cnt;
    }
}

Python3版:

class Solution:
    def countCollisions(self, directions: str) -> int:
        cnt = 0
        stack = []
        for ch in directions:
            if not stack:
                stack.append(ch)
                continue
            else:
                if ch == 'L':
                    if stack[-1] == 'S':
                        cnt += 1
                    elif stack[-1] == 'R':
                        cnt += 1
                        while stack and stack[-1] == 'R':
                            cnt += 1
                            stack.pop()
                        stack.append('S')
                elif ch == 'S':
                    while stack and stack[-1] == 'R':
                        cnt += 1
                        stack.pop()
                    stack.append('S')
                else:
                    # ch == 'R'
                    stack.append('R')
        return cnt

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串长度。

  • 空间复杂度:O(n).

  • 23
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值