comments | difficulty | edit_url | rating | source | tags | |||||
---|---|---|---|---|---|---|---|---|---|---|
true |
困难 |
2530 |
第 230 场周赛 Q4 |
|
在一条单车道上有 n
辆车,它们朝着同样的方向行驶。给你一个长度为 n
的数组 cars
,其中 cars[i] = [positioni, speedi]
,它表示:
positioni
是第i
辆车和道路起点之间的距离(单位:米)。题目保证positioni < positioni+1
。speedi
是第i
辆车的初始速度(单位:米/秒)。
简单起见,所有车子可以视为在数轴上移动的点。当两辆车占据同一个位置时,我们称它们相遇了。一旦两辆车相遇,它们会合并成一个车队,这个车队里的车有着同样的位置和相同的速度,速度为这个车队里 最慢 一辆车的速度。
请你返回一个数组 answer
,其中 answer[i]
是第 i
辆车与下一辆车相遇的时间(单位:秒),如果这辆车不会与下一辆车相遇,则 answer[i]
为 -1
。答案精度误差需在 10-5
以内。
示例 1:
输入: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 的车队。
示例 2:
输入:cars = [[3,4],[5,4],[6,3],[9,1]] 输出:[2.00000,1.00000,1.50000,-1.00000]
提示:
1 <= cars.length <= 105
1 <= positioni, speedi <= 106
positioni < positioni+1
由于每一辆车最终追上其右边第一辆车的时间与其左边的车没有关系,因此,我们可以从右往左遍历,计算每辆车与其右边第一辆车相遇的时间。
具体地,我们维护一个栈,栈中存放的是车辆的编号,栈顶元素表示当前最慢的车辆编号,栈底元素表示当前最快的车辆编号。
当我们遍历到第
遍历完所有车辆后,即可得到答案。
时间复杂度
class Solution:
def getCollisionTimes(self, cars: List[List[int]]) -> List[float]:
stk = []
n = len(cars)
ans = [-1] * n
for i in range(n - 1, -1, -1):
while stk:
j = stk[-1]
if cars[i][1] > cars[j][1]:
t = (cars[j][0] - cars[i][0]) / (cars[i][1] - cars[j][1])
if ans[j] == -1 or t <= ans[j]:
ans[i] = t
break
stk.pop()
stk.append(i)
return ans
class Solution {
public double[] getCollisionTimes(int[][] cars) {
int n = cars.length;
double[] ans = new double[n];
Arrays.fill(ans, -1.0);
Deque<Integer> stk = new ArrayDeque<>();
for (int i = n - 1; i >= 0; --i) {
while (!stk.isEmpty()) {
int j = stk.peek();
if (cars[i][1] > cars[j][1]) {
double t = (cars[j][0] - cars[i][0]) * 1.0 / (cars[i][1] - cars[j][1]);
if (ans[j] < 0 || t <= ans[j]) {
ans[i] = t;
break;
}
}
stk.pop();
}
stk.push(i);
}
return ans;
}
}
class Solution {
public:
vector<double> getCollisionTimes(vector<vector<int>>& cars) {
int n = cars.size();
vector<double> ans(n, -1.0);
stack<int> stk;
for (int i = n - 1; ~i; --i) {
while (stk.size()) {
int j = stk.top();
if (cars[i][1] > cars[j][1]) {
double t = (cars[j][0] - cars[i][0]) * 1.0 / (cars[i][1] - cars[j][1]);
if (ans[j] < 0 || t <= ans[j]) {
ans[i] = t;
break;
}
}
stk.pop();
}
stk.push(i);
}
return ans;
}
};
func getCollisionTimes(cars [][]int) []float64 {
n := len(cars)
ans := make([]float64, n)
for i := range ans {
ans[i] = -1.0
}
stk := []int{}
for i := n - 1; i >= 0; i-- {
for len(stk) > 0 {
j := stk[len(stk)-1]
if cars[i][1] > cars[j][1] {
t := float64(cars[j][0]-cars[i][0]) / float64(cars[i][1]-cars[j][1])
if ans[j] < 0 || t <= ans[j] {
ans[i] = t
break
}
}
stk = stk[:len(stk)-1]
}
stk = append(stk, i)
}
return ans
}