力扣每日一题

2731. 移动机器人 - 力扣(LeetCode) 

力扣每日一题_第1张图片

暴力模拟如下 :

class Solution {
public:
    const int mod = 1e9 + 7;
    int sumDistance(vector& 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; 
    }
};

力扣每日一题_第2张图片 

看数据范围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& 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; 
    }
};

再看数据范围 

力扣每日一题_第3张图片 

 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& 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; 
    }
};

 

你可能感兴趣的:(力扣每日一题签到,leetcode,算法,职场和发展)