现有 n
个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。
给你下标从 0 开始的两个整数数组 positions
、healths
和一个字符串 directions
(directions[i]
为 'L' 表示 向左 或 'R' 表示 向右)。 positions
中的所有整数 互不相同 。
所有机器人以 相同速度 同时 沿给定方向在路线上移动。如果两个机器人移动到相同位置,则会发生 碰撞 。
如果两个机器人发生碰撞,则将 健康度较低 的机器人从路线中 移除 ,并且另一个机器人的健康度 减少 1 。幸存下来的机器人将会继续沿着与之前 相同 的方向前进。如果两个机器人的健康度相同,则将二者都从路线中移除。
请你确定全部碰撞后幸存下的所有机器人的 健康度 ,并按照原来机器人编号的顺序排列。即机器人 1 (如果幸存)的最终健康度,机器人 2 (如果幸存)的最终健康度等。 如果不存在幸存的机器人,则返回空数组。
在不再发生任何碰撞后,请你以数组形式,返回所有剩余机器人的健康度(按机器人输入中的编号顺序)。
注意:位置 positions
可能是乱序的。
示例 1:
输入:positions = [5,4,3,2,1], healths = [2,17,9,15,10], directions = "RRRRR" 输出:[2,17,9,15,10] 解释:在本例中不存在碰撞,因为所有机器人向同一方向移动。所以,从第一个机器人开始依序返回健康度,[2, 17, 9, 15, 10] 。
示例 2:
输入:positions = [3,5,2,6], healths = [10,10,15,12], directions = "RLRL" 输出:[14] 解释:本例中发生 2 次碰撞。首先,机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。接下来,机器人 3 和机器人 4 将会发生碰撞,由于机器人 4 的健康度更小,则它会被移除,而机器人 3 的健康度变为 15 - 1 = 14 。仅剩机器人 3 ,所以返回 [14] 。
示例 3:
输入:positions = [1,2,5,6], healths = [10,10,11,11], directions = "RLRL" 输出:[] 解释:机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。机器人 3 和机器人 4 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。所以返回空数组 [] 。
提示:
1 <= positions.length == healths.length == directions.length == n <= 10^5
1 <= positions[i], healths[i] <= 10^9
directions[i] == 'L'
或directions[i] == 'R'
positions
中的所有值互不相同
提示 1
Process the robots in the order of their positions to ensure that we process the collisions correctly.
提示 2
To optimize the solution, use a stack to keep track of the surviving robots as we iterate through the positions.
提示 3
Instead of simulating each collision, check the current robot against the top of the stack (if it exists) to determine if a collision occurs.
解法1:栈
类似题型:LeetCode 735. 小行星碰撞-CSDN博客
LeetCode 2211. 统计道路上的碰撞次数-CSDN博客
算法逻辑
- 数据结构选择:使用数组来存储机器人的信息,包括编号、位置、健康度和移动方向。
- 排序:首先根据机器人的位置对列表进行排序,确保按顺序处理碰撞。
- 栈的使用:使用栈来跟踪幸存的机器人。栈顶是当前位置最近的机器人。
- 模拟碰撞:遍历排序后的机器人数组,对于每个机器人,检查是否与栈顶的机器人发生碰撞:
- 如果当前机器人向左移动(
'L'
),并且栈顶机器人向右移动('R'
),则进行碰撞检测。 - 如果两个机器人健康度相同,它们都会被淘汰。
- 如果当前机器人健康度低于栈顶机器人,当前机器人被淘汰,栈顶机器人健康度减1。
- 如果当前机器人健康度高于栈顶机器人,栈顶机器人被淘汰,当前机器人健康度减1。
- 如果当前机器人向左移动(
- 更新栈:根据碰撞结果更新栈,可能包括弹出栈顶元素或将当前机器人压入栈。
- 结果生成:遍历结束后,栈中剩余的元素即为幸存的机器人。根据机器人的原始编号对栈进行排序,然后提取健康度作为结果。
算法步骤
- 初始化:创建一个数组
robots
,包含每个机器人的编号、位置、健康度和移动方向。 - 排序:按照机器人的位置对
robots
数组进行排序。 - 初始化栈:创建一个空栈
stack
。 - 遍历机器人数组:
- 对于每个机器人,执行以下步骤:
- 设置
live
标志为True
,表示机器人初始状态为存活。 - 检查栈顶机器人(如果有)和当前机器人是否满足碰撞条件。
- 如果发生碰撞,根据健康度决定哪个机器人存活或都被淘汰,并更新
live
标志和栈。
- 设置
- 对于每个机器人,执行以下步骤:
- 压栈:如果
live
标志为True
,将当前机器人压入栈。 - 排序并提取结果:遍历结束后,根据机器人编号对栈进行排序,然后提取每个机器人的健康度,返回结果。
Java版:
class Solution {
public List<Integer> survivedRobotsHealths(int[] positions, int[] healths, String directions) {
int n = positions.length;
int[][] robots = new int[n][4];
for (int i = 0; i < n; i++) {
robots[i][0] = i;
robots[i][1] = positions[i];
robots[i][2] = healths[i];
robots[i][3] = directions.charAt(i) == 'L' ? 0 : 1;
}
Arrays.sort(robots, (a, b) -> a[1] - b[1]);
Deque<int[]> stack = new LinkedList<>();
for (int i = 0; i < n; i++) {
boolean live = true;
while (live && robots[i][3] == 0 && !stack.isEmpty() && stack.peek()[3] == 1) {
if (robots[i][2] == stack.peek()[2]) {
live = false;
stack.pop();
} else if (robots[i][2] < stack.peek()[2]) {
live = false;
stack.peek()[2]--;
} else {
stack.pop();
robots[i][2]--;
}
}
if (live) {
stack.push(robots[i]);
}
}
List<int[]> list = new ArrayList<>(stack);
Collections.sort(list, (a, b) -> a[0] - b[0]);
return list.stream().map(robot -> robot[2]).collect(Collectors.toList());
}
}
Python3版:
class Solution:
def survivedRobotsHealths(self, positions: List[int], healths: List[int], directions: str) -> List[int]:
robots = [[i, pos, health, direction] for i, (pos, health, direction) in enumerate(zip(positions, healths, directions))]
robots.sort(key = lambda x: x[1])
stack = []
for robot in robots:
live = True
while live and robot[3] == 'L' and stack and stack[-1][3] == 'R':
if robot[2] == stack[-1][2]:
live = False
stack.pop()
elif robot[2] < stack[-1][2]:
live = False
stack[-1][2] -= 1
else:
stack.pop()
robot[2] -= 1
if live:
stack.append(robot)
stack.sort(key = lambda x: x[0])
return [s[2] for s in stack]
复杂度分析
- 时间复杂度:O(nlogn),其中 n 为 positions 的长度。瓶颈在排序上。
- 空间复杂度:O(n)。