leetcode 2751. 机器人碰撞 困难

现有 n 个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。

给你下标从 0 开始的两个整数数组 positionshealths 和一个字符串 directionsdirections[i]'L' 表示 向左'R' 表示 向右 )。 positions 中的所有整数 互不相同

所有机器人以 相同速度 同时 沿给定方向在路线上移动。如果两个机器人移动到相同位置,则会发生 碰撞

如果两个机器人发生碰撞,则将 健康度较低 的机器人从路线中 移除 ,并且另一个机器人的健康度 减少 1 。幸存下来的机器人将会继续沿着与之前 相同 的方向前进。如果两个机器人的健康度相同,则将二者都从路线中移除。

请你确定全部碰撞后幸存下的所有机器人的 健康度 ,并按照原来机器人编号的顺序排列。即机器人 1 (如果幸存)的最终健康度,机器人 2 (如果幸存)的最终健康度等。 如果不存在幸存的机器人,则返回空数组。

在不再发生任何碰撞后,请你以数组形式,返回所有剩余机器人的健康度(按机器人输入中的编号顺序)。

注意: 位置 positions 可能是乱序的。

示例 1:

复制代码
输入:positions = [5,4,3,2,1], healths = [2,17,9,15,10], directions = "RRRRR"
输出:[2,17,9,15,10]
解释:在本例中不存在碰撞,因为所有机器人向同一方向移动。所以,从第一个机器人开始依序返回健康度,[2, 17, 9, 15, 10] 。

示例 2:

复制代码
输入:positions = [3,5,2,6], healths = [10,10,15,12], directions = "RLRL"
输出:[14]
解释:本例中发生 2 次碰撞。首先,机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。接下来,机器人 3 和机器人 4 将会发生碰撞,由于机器人 4 的健康度更小,则它会被移除,而机器人 3 的健康度变为 15 - 1 = 14 。仅剩机器人 3 ,所以返回 [14] 。

示例 3:

复制代码
输入:positions = [1,2,5,6], healths = [10,10,11,11], directions = "RLRL"
输出:[]
解释:机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。机器人 3 和机器人 4 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。所以返回空数组 [] 。

提示:

  • 1 <= positions.length == healths.length == directions.length == n <= 10^5
  • 1 <= positions[i], healths[i] <= 10^9
  • directions[i] == 'L'directions[i] == 'R'
  • positions 中的所有值互不相同

分析:先将所有的机器人按照 positions 位置从左到右排序,并用一个栈,记录当前有多少个向右走的机器人。排好序之后,从左到右遍历所有的机器人,如果这个机器人是向右走的,则先存入栈中;如果是向左走的,则先检查栈是否为空,如果为空,则这个机器人不会发生碰撞,可以幸存,如果栈不为空,则取出栈顶的机器人,对比健康度进行碰撞,直到栈为空或者这个机器人被移除为止。检查完所有的机器人后,栈里剩下的机器人都是幸存的机器人。按照原来的输入顺序排序后返回即可。

cpp 复制代码
class Solution {
public:
    typedef struct node
    {
        int pos,hea,ind;
        char dir;
    }node;
    static bool cmp(const node a,const node b)
    {
        return a.pos<b.pos;
    }
    static bool cmp2(const node a,const node b)
    {
        return a.ind<b.ind;
    }
    vector<int> survivedRobotsHealths(vector<int>& positions, vector<int>& healths, string directions) {
        int n=positions.size();
        vector<node>vec,res;
        for(int i=0;i<n;++i)
        {
            node temp;temp.pos=positions[i],temp.hea=healths[i],temp.dir=directions[i],temp.ind=i;
            vec.push_back(temp);
        }
        sort(vec.begin(),vec.end(),cmp);
        stack<node>sta;
        for(int i=0;i<n;++i)
        {
            if(vec[i].dir=='L')
            {
                if(sta.size()==0)res.push_back(vec[i]);
                else
                {
                    node rob=sta.top();sta.pop();
                    if(rob.hea>vec[i].hea)rob.hea--,sta.push(rob);
                    else if(rob.hea<vec[i].hea)vec[i].hea--,i--;
                }
            }
            else if(vec[i].dir=='R')sta.push(vec[i]);
        }
        while(!sta.empty())
            res.push_back(sta.top()),sta.pop();
        sort(res.begin(),res.end(),cmp2);
        
        vector<int>ans;
        for(int i=0;i<res.size();++i)
            ans.push_back(res[i].hea);
        return ans;
    }
};
相关推荐
Liangwei Lin4 小时前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
YL200404266 小时前
047从前序与中序遍历序列构造二叉树
算法·leetcode
如竟没有火炬9 小时前
字符串相乘——int数组转字符串
开发语言·数据结构·python·算法·leetcode·深度优先
YL2004042612 小时前
046二叉树展开为链表
数据结构·leetcode·链表
如竟没有火炬13 小时前
至少有K个重复字符的最长子串
开发语言·数据结构·python·算法·leetcode·动态规划
水蓝烟雨14 小时前
2359. 找到离给定两个节点最近的节点
算法·leetcode
阿Y加油吧15 小时前
二刷动态规划经典题:从打家劫舍到完全平方数,Java 实现复盘与优化
leetcode
阿Y加油吧15 小时前
二刷 LeetCode:爬楼梯与杨辉三角,Java 实现复盘
java·算法·leetcode
凌波粒15 小时前
LeetCode--101. 对称二叉树(二叉树)
算法·leetcode·职场和发展
_深海凉_15 小时前
LeetCode热题100-二叉树的最大深度
算法·leetcode·职场和发展