一、题目描述:
二、思路分析:
当时周赛做到第四题就剩十几分钟了,模板套不进去就没做,看起来是一道相对而行的题,但写代码又很乏力,写不出来。
不妨先冷静分析下:
1. 同向而行速度不同位置不同的几个车,什么时候会相遇呢?
后面的车速度不同的时候,这个肯定大家都想得到
2. 那么速度不同的三辆车,从左往右数ABC,速度依次递减,会怎么样呢?
大多数人就是纠结AB一定会超过C,但是在这个过程中,A先超过B,还是B先超过C,就不好说了
我们回到题干,发现了关键,
一旦两辆车相遇,它们会合并成一个车队,这个车队里的车有着同样的位置和相同的速度,速度为这个车队里 最慢 一辆车的速度。
这个看起来只是更复杂的条件其实暗示了我们,无论是A先超过B,还是B先超过C,我们能确定是:超过C的一定是B,因为A超过B以后,A就不存在了。
这个需要反应一下,想清楚这点这道题迎刃而解,想不清楚就没得做了。
在我们知道第i辆车只会被第i-1辆车超过的时候,我们就可以从右往左依次遍历。
对于第i辆车,
- 如果前面的速度比我快,那我一定超不过
- 如果前面的速度比我慢,且前面的车没有超车,那我早晚能超过。
- 如果前面的速度比我慢,且前面的车第t秒超车,那我计算下我t秒内是否能超车
问题就迎刃而解了。
三、AC 代码:
class Solution {
public:
vector<double> getCollisionTimes(vector<vector<int>>& cars) {
vector<double>ans(cars.size());
stack<int> S;
for(int i=cars.size()-1;i>=0;i--){
while(S.size()){ // stack 非空
if(cars[S.top()][1] >= cars[i][1])S.pop();
else{ // 追得上
if(ans[S.top()] == -1)break;
double d=ans[S.top()]*(cars[i][1]-cars[S.top()][1]);
if(d>cars[S.top()][0]-cars[i][0])break;
else S.pop();
}
}
if(S.empty()){
ans[i] = -1;
}else{
printf("2");
ans[i]= double(cars[S.top()][0]-cars[i][0])/double(cars[i][1]-cars[S.top()][1]);
}
S.push(i);
}
return ans;
}
};
四、总结:
最近时常遇到一些非模板题,虽然看标签有说单调栈的,但单调栈我也是学过,这题实在不能说用单调栈,就像我这个活动发的第一题,实在不能说他是动态规划,记得最开始做leetCode的时候,什么数据结构算法都不是很懂,反而喜欢做这类”活“题,学了模板之后做题就开始僵化了,尤其周赛,时间紧张,更是大脑空白,这两天做题发文章有余,而业绩成效甚微,也算是个小遗憾。但生活还是得往前看。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情