2731. 移动机器人
数轴上有一系列点,每个时刻朝左/右移动一个单位,两个点若相遇则立刻掉头。现给定初始位置,初始移动方向与移动总时间,给出所有点最终位置之间的间距之和(对1e7取模)。
题目链接
中等题,思路很清晰,主要难度在于细节。
题目具体简介中提示,所有点(机器人)之间是没有区别的,因此相撞可以认为完全不存在(即擦肩而过)。
因此,每个点相当于朝着自己的初始方向走了(总时刻)步,最终位置无需迭代,可以直接产出。
之后跑个循环,统计每两个点之间的距离,取绝对值累加就好啦……
提示:
2 <= nums.length <= 10^5
超时,寄。
重新考虑得到最终距离后如何算累计距离,从O(N^2)
降到O(N)
。
容易想到排序,使点在数轴上有序(由于点间无区别)。
自己想的
对于从左到右的第i段距离,在整个统计中会使用(总段数-i+1)*i
次。
从小到大枚举
pos
[
i
]
\textit{pos}[i]
pos[i],此时左边有
i
i
i个数字,右边有
n
−
i
n−i
n−i个数字(算上
pos
[
i
]
\textit{pos}[i]
pos[i]),所以共有
i
×
(
n
−
i
)
i\times(n−i)
i×(n−i) 对数字在计算距离时会累加
pos
[
i
]
−
pos
[
i
−
1
]
\textit{pos}[i] - \textit{pos}[i - 1]
pos[i]−pos[i−1]。我们依次遍历完
[
1
,
n
−
1
]
[1,n−1]
[1,n−1]范围内所有的
pos
[
i
]
\textit{pos}[i]
pos[i],将
(
pos
[
i
]
−
pos
[
i
−
1
]
)
×
i
×
(
n
−
i
)
(\textit{pos}[i] - \textit{pos}[i - 1]) \times i \times (n - i)
(pos[i]−pos[i−1])×i×(n−i)累加到答案中即可。
排序后计算,这样肯定过啦——
提示:
-2 * 10^9 <= nums[i] <= 2 * 10^9
RE,又寄。
记得使用long long。
class Solution {
public:
int sumDistance(vector<int>& nums, string s, int d) {
const int mnum = 1000000007;
int leftmost = 2000000000, rightmost = -2000000000;
for(int i=0;i<s.length();i++){
nums[i] = nums[i]+((s[i] == 'L')?-1:1)*d;
leftmost = min(leftmost, nums[i]);
rightmost = max(rightmost, nums[i]);
}
long long ans = 0;
sort(nums.begin(), nums.end());
for(int i=1;i<s.length();i++){
long long l = nums[i-1], r = nums[i];
ans = (ans + (((r-l)%mnum)*(i*(s.length()-i))%mnum))%mnum;
}
return ans;
}
};