返回介绍

solution / 1700-1799 / 1776.Car Fleet II / README

发布于 2024-06-17 01:03:14 字数 4759 浏览 0 评论 0 收藏 0

1776. 车队 II

English Version

题目描述

在一条单车道上有 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

解法

方法一:栈

由于每一辆车最终追上其右边第一辆车的时间与其左边的车没有关系,因此,我们可以从右往左遍历,计算每辆车与其右边第一辆车相遇的时间。

具体地,我们维护一个栈,栈中存放的是车辆的编号,栈顶元素表示当前最慢的车辆编号,栈底元素表示当前最快的车辆编号。

当我们遍历到第 $i$ 辆车时,如果第 $i$ 辆车的速度大于栈顶元素对应的车辆 $j$ 的速度,此时我们计算两车相遇的时间,记为 $t$。如果车辆 $j$ 与右边车辆不会相遇,或者 $t$ 小于等于 $j$ 与右辆车相遇的时间,说明车辆 $i$ 可以在 $t$ 时间追上车辆 $j$,更新答案。否则,说明车辆 $i$ 不会与车辆 $j$ 相遇,我们将车辆 $j$ 出栈,继续判断车辆 $i$ 与栈顶元素对应的车辆相遇的时间。如果栈为空,说明车辆 $i$ 不会与任何车辆相遇,更新答案为 $-1$。最后,将车辆 $i$ 入栈。

遍历完所有车辆后,即可得到答案。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为车辆数量。

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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文