欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 学习记录:js算法(十一):车队

学习记录:js算法(十一):车队

2025/1/18 1:28:09 来源:https://blog.csdn.net/weixin_48677331/article/details/141414713  浏览:    关键词:学习记录:js算法(十一):车队

文章目录

    • 车队
      • 我的思路:数组循环
      • 网上思路:使用栈来解决
    • 总结

车队

在一条单行道上,有 n 辆车开往同一目的地。目的地是几英里以外的 target 。
给定两个整数数组 position 和 speed ,长度都是 n ,其中 position[i] 是第 i 辆车的位置, speed[i] 是第 i 辆车的速度(单位是英里/小时)。
一辆车永远不会超过前面的另一辆车,但它可以追上去,并以较慢车的速度在另一辆车旁边行驶。
车队 是指并排行驶的一辆或几辆汽车。车队的速度是车队中 最慢 的车的速度。
即便一辆车在 target 才赶上了一个车队,它们仍然会被视作是同一个车队。
返回到达目的地的车队数量 。

示例 1:
输入:target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
输出:3
解释:
从 10(速度为 2)和 8(速度为 4)开始的车会组成一个车队,它们在 12 相遇。车队在 target 形成。
从 0(速度为 1)开始的车不会追上其它任何车,所以它自己是一个车队。
从 5(速度为 1) 和 3(速度为 3)开始的车组成一个车队,在 6 相遇。车队以速度 1 移动直到它到达 target。示例 2:
输入:target = 10, position = [3], speed = [3]
输出:1
解释:
只有一辆车,因此只有一个车队。示例 3:
输入:target = 100, position = [0,2,4], speed = [4,2,1]
输出:1
解释:
从 0(速度为 4) 和 2(速度为 2)开始的车组成一个车队,在 4 相遇。从 4 开始的车(速度为 1)移动到了 5。
然后,在 4(速度为 2)的车队和在 5(速度为 1)的车成为一个车队,在 6 相遇。车队以速度 1 移动直到它到达 target。

我的思路:数组循环

var carFleet = function (target, position, speed) {const times = [];for (let i = 0; i < position.length; i++) {times[i] = (target - position[i]) / speed[i];}position.sort((a, b) => a - b);times.sort((a, b) => position[times.indexOf(a)] - position[times.indexOf(b)]);let cars = 0;let lastTime = 0;for (let i = position.length - 1; i >= 0; i--) {if (lastTime < times[i]) {cars++;lastTime = times[i];}}return cars;
};

讲解

  1. 首先得理清思路:每辆车到达终点的时间,是根据 (终点 - 当前距离)/ 速度 得到,然后根据 position 内部距离按从小到大排序,确保从后向前可以正确地比较到达时间。然后就是循环的问题了,考虑到如果从前往后循环,会导致如果一辆车会追上前面的车,可能会在后续的遍历中再次计算这个车队的到达时间,导致重复计数。比如,若 车A车B 合并成一个车队,后续再遇到 车C 时,可能会错误地将 车A 和 车B 的计数再次计算。所以这里就用了从后往前的循环。因为只需要考虑前车即可,所以后一辆车到达目标的时间小于或等于前一辆车的到达时间,代表后车追上前车,形成一个车队。
  2. 创建一个 time(时间数组),用来存储每辆车跑到 target(终点) 需要的时间
  3. 创建一个 cars(新车队数量) 和 lastTime(车子最后到达终点的时间)
  4. 步骤2 的目的:从最后一辆车开始向前遍历,检查每辆车的到达时间。如果当前车的到达时间 time[i] 大于 lastTime,则说明这一辆车会形成一个新的车队,增加车队计数,并更新 lastTime 为当前车的到达时间。

网上思路:使用栈来解决

var carFleet = function (target, position, speed) {const n = position.length;const times = [];for (let i = 0; i < n; i++) {times.push((target - position[i]) / speed[i]);}const cars = position.map((pos, idx) => [pos, times[idx]]).sort((a, b) => b[0] - a[0]);const stack = [];for (let i = 0; i < n; i++) {const time = cars[i][1];if (stack.length === 0 || time > stack[stack.length - 1]) {stack.push(time);}}return stack.length;
};

讲解

  1. 首先计算每辆车到达目标的时间并存储在 times 数组中。
  2. 然后将位置和时间结合成一个数组 cars,并按位置降序排序。
  3. 使用栈来管理车队:我们从后向前遍历这些车,使用一个栈来存储车队的到达时间。这样可以帮助我们判断当前车是否会与前面的车形成同一车队。如果当前车的到达时间小于或等于栈顶车的到达时间,说明当前车会追上前面的车,形成同一车队。如果当前车的到达时间大于栈顶车的到达时间,说明当前车会单独形成一个新的车队。
  4. 最后返回栈的长度,即为车队的数量。

总结

第一反应还是想着通过循环来解决问题了,没往栈上面想,但是回头看了看这两种思路,其实都是差不多的,核心还是先计算所有车辆到达时间,然后通过排序确保可以正确地比较到达时间。最后就是循环了。万变不离循环~

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com