leecode.5692. 车队 II

题目

在一条单车道上有 n 辆车,它们朝着同样的方向行驶。给你一个长度为 n 的数组 cars ,其中 cars[i] = [positioni, speedi] ,它表示:

  • positioni 是第 i 辆车和道路起点之间的距离(单位:米)。题目保证 positioni < positioni+1 。
  • speedi 是第 i 辆车的初始速度(单位:米/秒)。

简单起见,所有车子可以视为在数轴上移动的点。当两辆车占据同一个位置时,我们称它们相遇了。一旦两辆车相遇,它们会合并成一个车队,这个车队里的车有着同样的位置和相同的速度,速度为这个车队里 最慢 一辆车的速度。

请你返回一个数组 answer ,其中 answer[i] 是第 i 辆车与下一辆车相遇的时间(单位:秒),如果这辆车不会与下一辆车相遇,则 answer[i] 为 -1 。答案精度误差需在 10-5 以内。

示例一

输入:cars = [[1,2],[2,1],[4,3],[7,2]]
输出:[1.00000,-1.00000,3.00000,-1.00000]
解释:经过恰好 1 秒以后,第一辆车会与第二辆车相遇,并形成一个 1 m/s 的车队。经过恰好 3 秒以后,第三辆车会与第四辆车相遇,并形成一个 2 m/s 的车队。

思路分析

  • 对于A,B两个车来说,A车在前,B车在后。A车和B车相遇的条件,一定是首先A的速度要比B快,其次在A和B相遇的时候,B没有其他的车相遇。
  • 我们用栈来存储目前的后面的车的编号;用ans的时间来标志后面的车B是否和B后面的车C相遇。

代码

class Solution {
public:
    vector<double> getCollisionTimes(vector<vector<int>>& cars) {
        vector<double> ans(cars.size(), 0);
        stack<int> s;
        //相遇应该满足的条件是:左边的车子比右边的车子的速度快,那么两个车相遇的时候,速度同步成那个小的速度。
        for(int i = cars.size() - 1;i >= 0;i--){
            while(s.size()){//目前栈里面存在没有消失的右边的车子
                if(cars[i][1] <= cars[s.top()][1]){
                    //证明当前车子的速度比后面的车子的速度小,此时是不会发生相遇,那么后面的这个车子pop出
                    s.pop();
                }else{
                    if(ans[s.top()] < 0) //此时后面的这个车不会消失,我们就去试图和这个车相遇 
                        break;
        //如果遇到了可以相遇的,当时因为大家都是在追赶自己后面,假设现在是A,B,C三辆车,A的确比B快,但是在A追上B之前,B已经追上了C,那么此时A追不上B.
                    //判断在B和C相遇之前,A是否可以追上B
                    double dis = ans[s.top()] * (cars[i][1] - cars[s.top()][1]);
                    //满足这个条件证明是追不上的,将后面的这个车pop出
                    if(dis < cars[s.top()][0] - cars[i][0]) s.pop();
                    //否则,计算后面的相遇时间
                    else break;
                }
            }
            //如果当前栈是空的,那么此时证明追不上任何的车子
            if(s.size() == 0) ans[i] = -1.0;
            else{//否则计算时间。
                ans[i] = (double)(cars[s.top()][0] - cars[i][0]) / (double)(cars[i][1] - cars[s.top()][1]);
            }
            //将当前的车子重新入栈
            s.push(i);
        }
        //返回结果
        return ans;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值