6426. 移动机器人
有一些机器人分布在一条无限长的数轴上,他们初始坐标用一个下标从 0 开始的整数数组 nums
表示。当你给机器人下达命令时,它们以每秒钟一单位的速度开始移动。
给你一个字符串 s
,每个字符按顺序分别表示每个机器人移动的方向。'L'
表示机器人往左或者数轴的负方向移动,'R'
表示机器人往右或者数轴的正方向移动。
当两个机器人相撞时,它们开始沿着原本相反的方向移动。
请你返回指令重复执行 d
秒后,所有机器人之间两两距离之和。由于答案可能很大,请你将答案对 109 + 7
取余后返回。
注意:
i
和 j
的两个机器人,(i,j)
和 (j,i)
视为相同的坐标对。也就是说,机器人视为无差别的。当两个机器人在同一时刻占据相同的位置时,就会相撞。
例如,如果一个机器人位于位置 0 并往右移动,另一个机器人位于位置 2 并往左移动,下一秒,它们都将占据位置 1,并改变方向。再下一秒钟后,第一个机器人位于位置 0 并往左移动,而另一个机器人位于位置 2 并往右移动。
例如,如果一个机器人位于位置 0 并往右移动,另一个机器人位于位置 1 并往左移动,下一秒,第一个机器人位于位置 0 并往左行驶,而另一个机器人位于位置 1 并往右移动。
示例 1:
输入:nums = [-2,0,2], s = "RLL", d = 3 输出:8 解释: 1 秒后,机器人的位置为 [-1,-1,1] 。现在下标为 0 的机器人开始往左移动,下标为 1 的机器人开始往右移动。 2 秒后,机器人的位置为 [-2,0,0] 。现在下标为 1 的机器人开始往左移动,下标为 2 的机器人开始往右移动。 3 秒后,机器人的位置为 [-3,-1,1] 。 下标为 0 和 1 的机器人之间距离为 abs(-3 - (-1)) = 2 。 下标为 0 和 2 的机器人之间的距离为 abs(-3 - 1) = 4 。 下标为 1 和 2 的机器人之间的距离为 abs(-1 - 1) = 2 。 所有机器人对之间的总距离为 2 + 4 + 2 = 8 。
示例 2:
输入:nums = [1,0], s = "RL", d = 2 输出:5 解释: 1 秒后,机器人的位置为 [2,-1] 。 2 秒后,机器人的位置为 [3,-2] 。 两个机器人的距离为 abs(-2 - 3) = 5 。
提示:
2 <= nums.length <= 105
-2 * 109 <= nums[i] <= 2 * 109
0 <= d <= 109
nums.length == s.length
s
只包含 'L'
和 'R'
。nums[i]
互不相同。原站题解
php 解法, 执行用时: 164 ms, 内存消耗: 30.5 MB, 提交时间: 2023-10-10 09:40:00
class Solution { /** * @param Integer[] $nums * @param String $s * @param Integer $d * @return Integer */ function sumDistance($nums, $s, $d) { $mod = 10**9 + 7; $n = count($nums); $pos = []; for ( $i = 0; $i < $n; $i++ ) { $pos[] = $s[$i] == 'R' ? $nums[$i] + $d: $nums[$i] - $d; } sort($pos); $ans = 0; for ( $i = 1; $i < $n; $i++ ) { $ans += ($pos[$i] - $pos[$i - 1]) * $i % $mod * ($n - $i) % $mod; $ans %= $mod; } return $ans; } }
javascript 解法, 执行用时: 144 ms, 内存消耗: 59.2 MB, 提交时间: 2023-10-10 07:44:05
/** * @param {number[]} nums * @param {string} s * @param {number} d * @return {number} */ var sumDistance = function(nums, s, d) { const mod = 1e9 + 7; n = nums.length; pos = new Array(n).fill(0); for (let i = 0; i < n; i++) { pos[i] = s[i] === 'L' ? nums[i] - d : nums[i] + d; } pos.sort((a, b) => a - b); let res = 0; for (let i = 1; i < n; i++) { res += (pos[i] - pos[i - 1]) * i % mod * (n - i) % mod; res %= mod; } return res; };
java 解法, 执行用时: 11 ms, 内存消耗: 53.4 MB, 提交时间: 2023-10-10 07:43:43
class Solution { static final int MOD = 1000000007; public int sumDistance(int[] nums, String s, int d) { int n = nums.length; long[] pos = new long[n]; for (int i = 0; i < n; i++) { if (s.charAt(i) == 'L') { pos[i] = (long) nums[i] - d; } else { pos[i] = (long) nums[i] + d; } } Arrays.sort(pos); long res = 0; for (int i = 1; i < n; i++) { res += 1L * (pos[i] - pos[i - 1]) * i % MOD * (n - i) % MOD; res %= MOD; } return (int) res; } }
python3 解法, 执行用时: 152 ms, 内存消耗: 27.1 MB, 提交时间: 2023-06-11 09:10:24
class Solution: def sumDistance(self, nums: List[int], s: str, d: int) -> int: MOD = 10**9 + 7 n = len(nums) pos = [nums[i] + d if s[i] == 'R' else nums[i] - d for i in range(n)] pos.sort() ans = 0 for i in range(n-1): dis = pos[i+1] - pos[i] ans = (ans + (i+1)*(n-1-i)*dis) % MOD return ans
python3 解法, 执行用时: 144 ms, 内存消耗: 26.9 MB, 提交时间: 2023-06-11 09:09:55
class Solution: def sumDistance(self, nums: List[int], s: str, d: int) -> int: for i,j in enumerate(s): nums[i]=nums[i]+d if j=="R" else nums[i]-d nums.sort() total=0 n=len(nums) for i in range(1,n): total=total+(n-i)*i*(nums[i]-nums[i-1]) return total%1000000007
cpp 解法, 执行用时: 116 ms, 内存消耗: 91 MB, 提交时间: 2023-06-11 09:08:32
class Solution { public: int sumDistance(vector<int>& nums, string s, int d) { long long mod=1e9+7; int n=nums.size(); long long ans=0; for(int i=0;i<n;i++) { if(s[i]=='L') nums[i]-=d; else nums[i]+=d; } sort(nums.begin(),nums.end()); for(int i=0;i<n;i++) { ans+=(nums[i]*(long long)(i-(n-1-i))); ans%=mod; } return ans; } };
golang 解法, 执行用时: 88 ms, 内存消耗: 9.9 MB, 提交时间: 2023-06-11 09:08:10
func sumDistance(nums []int, s string, d int) int { for i := 0; i < len(nums); i++ { str := s[i : i+1] if str == "R" { nums[i] += d } else { nums[i] -= d } } sort.Ints(nums) arr := make([]int, len(nums)-1) for i := 0; i < len(arr); i++ { arr[i] = nums[i+1] - nums[0] } preArr := make([]int, len(arr)) for i := 0; i < len(preArr); i++ { preArr[i] = arr[i] if i != 0 { preArr[i] += preArr[i-1] } } var count int M := 1000000007 for i := 0; i < len(arr); i++ { s := preArr[len(preArr)-1] if i != 0 { s -= preArr[i-1] s -= (len(arr) - i) * arr[i-1] } count += s count %= M if count < 0 { count += M } } count %= M if count < 0 { count += M } return count }
python3 解法, 执行用时: 148 ms, 内存消耗: 26.7 MB, 提交时间: 2023-06-11 09:07:36
class Solution: def sumDistance(self, nums: List[int], s: str, d: int) -> int: nums = sorted([nums[j]+d if s[j]=='R' else nums[j]-d for j in range(len(nums))]) return sum(j*(len(nums)-j)*(nums[j]-nums[j-1]) for j in range(1,len(nums)))%(10**9+7)
cpp 解法, 执行用时: 120 ms, 内存消耗: 95.1 MB, 提交时间: 2023-06-11 09:06:37
/** * 前缀和 * 如果不区分两个相撞的机器人, 则两个相撞的机器人之后各自反向等价于两个机器人互不影响始终朝各自最初方向移动, * 所以可以求出经过d秒后所有机器人的位置, 之后排序+前缀和即可 **/ class Solution { public: typedef long long ll; ll mod = 1e9 + 7; int sumDistance(vector<int>& nums, string s, int d) { int n = nums.size(); vector<int> fin; for (int i = 0; i < n; i++) fin.push_back(s[i] == 'L' ? nums[i] - d : nums[i] + d); sort(fin.begin(), fin.end()); ll res = 0, pre = fin[0]; for (int i = 1; i < n; i++) { res += 1LL * fin[i] * i % mod - pre; res %= mod; pre += fin[i]; } return (res % mod + mod) % mod; } };