暴力模拟如下 :
class Solution {
public:
const int mod = 1e9 + 7;
int sumDistance(vector<int>& nums, string s, int d)
{
using i64 = long long;
int n = nums.size();
while(d--)
{
for(int i = 0;i < n;i++)
{
nums[i] += (s[i] == 'R' ? 1 : -1);
if(i && nums[i] == nums[i - 1])
swap(s[i], s[i - 1]);
}
}
i64 ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = i + 1;j < n;j++)
ans = (ans % mod + (abs(v[i] - v[j]) % mod)) % mod;
}
return ans;
}
};
看数据范围d == 1e9
可见该题解在处理d秒时的时间复杂度应当不超过O(n)
因此:上解需要优化
当我们碰撞的时候:
if(i && nums[i] == nums[i - 1])
swap(s[i], s[i - 1]);
交换俩者的方向,那也等于交换俩个机器人的效果,于是我们可以忽略碰撞影响,直接求d秒无碰撞的相对位置即可。
举一个简单的例子:
A = 0 == >> R
B = 2 == >> L
d = 10;
在1秒的时候交换方向
A = 1 == >> L
B = 1 == >> R
10s后:
A = -8 == >> L
B = 10 == >> R;
直接求相对距离
A = 10 == >> R
B = -8 == >> L
因此直接求d秒无碰撞的相对位置对最终答案无影响
此时: 由数据范围nums最大可为2e9,d 最大为1e9 >> 2147483647
爆int,需要i64数据类型进行存储
可得:
class Solution {
public:
const int mod = 1e9 + 7;
int sumDistance(vector<int>& nums, string s, int d)
{
using i64 = long long;
int n = nums.size();
vector<i64> v(n);
for(int i = 0;i < n; i++)
v[i] = nums[i] + (s[i] == 'R' ? d : -d);
i64 ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = i + 1;j < n;j++)
ans = (ans % mod + (abs(v[i] - v[j]) % mod)) % mod;
}
return ans;
}
};
再看数据范围
n的范围为[2,1e5]
仅看ans求值的第一轮循环1e5 * (1e5 - 1)显然超时
对于ans的求值过程有这么一种情况
对于任意 i [0,n]前有i个数,后有n - i个数 == >> i * (n - i)个数对都会进行一次加(v[i] - v[i- 1])的值
可得:
class Solution {
public:
const int mod = 1e9 + 7;
int sumDistance(vector<int>& nums, string s, int d)
{
using i64 = long long;
int n = nums.size();
vector<i64> v(n);
for(int i = 0;i < n; i++)
v[i] = nums[i] + (s[i] == 'R' ? d : -d);
sort(v.begin(),v.end());
i64 ans = 0;
for (int i = 1; i < n; i++)
{
ans = ((v[i] - v[i - 1]) * i % mod * (n - i) + ans) % mod;
}
return ans;
}
};