【Leetcode】2731. 移动机器人——1923
题目
2731. 移动机器人
有一些机器人分布在一条无限长的数轴上,他们初始坐标用一个下标从0开始的整数数组
nums表示。当你给机器人下达命令时,它们以每秒钟一单位的速度开始移动。给你一个字符串
s,每个字符按顺序分别表示每个机器人移动的方向。'L'表示机器人往左或者数轴的负方向移动,'R'表示机器人往右或者数轴的正方向移动。当两个机器人相撞时,它们开始沿着原本相反的方向移动。
请你返回指令重复执行
d秒后,所有机器人之间两两距离之和。由于答案可能很大,请你将答案对10^9 + 7取余后返回。
- \(2\leq nums.length\leq 10^5\)
- \(-2*10^9\leq nums[i] \leq 2*10^9\)
- \(0\leq d \leq 10^9\)
- \(nums.length==s.length\)
- \(s\)只包含
L和R- \(nums[i]\)互不相同
思路
计算最终位置
本题目也算是一个脑筋急转弯了,只要搞清楚机器人之间碰撞之后都反向运行的逻辑即可。
由于其实我们关心的是最终状态下每个机器人的位置,而并非与某一个机器人有关。因此不必要关系某个机器人在结束的位置在某个位置。
针对于碰撞即都反向运行的情况实际上碰撞前是一个向左一个向右,碰撞后仍然是一个向左一个向右,忽略机器人个体之间的差异,那么这个相撞实际上也就等于没有相撞。
因此可以直接算出来在结束的时候每个机器人的位置,当然了,针对于每个机器人分别在哪个位置是未知的。
class Solution:
def sumDistance(self, nums: List[int], s: str, d: int) -> int:
nums = [x + d if s[i] == 'R' else x - d for i, x in enumerate(nums)]
nums.sort()
计算机器人之间距离和
首先对于得到的每个机器人的位置进行排序。
之后考虑对于前i个机器人,如果我们已经知道了i-1位置的机器人与前边所有机器人之间的距离和\(D_{i-1}\),那么当前第i个机器人与前边所有机器人的距离和\(D_{i}\)就等于\(D_{i-1}+\Delta *i\),其中\(\Delta = nums[i]+nums[i-1]\)。
ans = 0
temp = 0
pre = nums[0]
for i, x in enumerate(nums):
temp += i * (x - pre)
ans = (ans+temp)%(10**9+7)
pre = x
此外,也可以考虑对于最终求解的所有位置的两两之和,每个相邻机器人的距离出现次数。
ans = 0
pre = nums[0]
n = len(nums)
for i, x in enumerate(nums):
ans = (ans+(i)*(n-i)*(x-pre)) % (10**9+7)
pre = x

浙公网安备 33010602011771号