暴力模拟如下 :
- 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
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
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;
- }
- };