【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\)只包含LR
  • \(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
posted @ 2024-10-16 14:40  TICSMC  阅读(17)  评论(0)    收藏  举报