6028. 统计道路上的碰撞次数

179 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第69天 2021.03.20

653. 两数之和 IV - 输入 BST

题目描述

  • 在一条无限长的公路上有 n 辆汽车正在行驶。汽车按从左到右的顺序按从 0 到 n - 1 编号,每辆车都在一个 独特的 位置。
  • 给你一个下标从 0 开始的字符串 directions ,长度为 n 。directions[i] 可以是 'L'、'R' 或 'S' 分别表示第 i 辆车是向 左 、向 右 或者 停留 在当前位置。每辆车移动时 速度相同 。
  • 碰撞次数可以按下述方式计算:
    • 当两辆移动方向 相反 的车相撞时,碰撞次数加 2 。
    • 当一辆移动的车和一辆静止的车相撞时,碰撞次数加 1 。
    • 碰撞发生后,涉及的车辆将无法继续移动并停留在碰撞位置。除此之外,汽车不能改变它们的状态或移动方向。
  • 返回在这条道路上发生的 碰撞总次数 。

提示

  • 1 <= directions.length <= 105
  • directions[i] 的值为 'L''R' 或 'S'

解题思路

  • 暴力模拟:根据当前车辆走向和前序车辆走向判断即可。正序遍历时特别注意往右走的车辆数目。例如,可找个特例 "RRLL" 捋一下思路。
  • 双指针:
  • 初始时刻,最左侧的连续 'L' 和最右侧的连续 'R' 均不会发生碰撞,而中间的非静止车辆则均会发生碰撞并静止。统计中间的非静止车辆数目即可。
  • 注意:发生碰撞的情况有3中:‘RL’、‘RS’、‘SL’。两个汽车发生碰撞后变为‘S’。将汽车发生碰撞的情况一一列出即可。
  • 注意:有可能一个位置的碰撞会引起连环撞,例如:‘RRRRRL’、‘RRRRRS’、‘SLLLLL’。

主要情况讨论

  • 记录当前位置向右的车的数量numR,和左侧是否有车相碰sw
  • 如果当前车向右,那么numR++,向右走的车多了一辆。
  • 如果当前车向左,先查看左侧是否有车相碰,如果有 那么相碰车的数量就加上numR + 11代表的是当前位置向左的这辆车)。如果没有车相碰,那么如果numR不等于0(也就是向左的车左面有numR辆向右的车),相碰的车数量加上numR + 1.
  • 如果当前车停止,同样查看左侧有没有向右的车,如果有则相碰的车数量加上numR

AC代码

var countCollisions = function(directions) {
  let l = len - 1;
  for(let i = 0; i < len; i++) {
    if(d[i] == 'R' || d[i] == 'S'){
      l = i;
      break;
    }
  }
  let r = 0;
  for(let i = len - 1; i >= 0; i--) {
    if(d[i] == 'L' || d[i] == 'S'){
      r = i;
      break;
    }
  }
  if(l >= r) return ans;
  for(let i = l; i <= r; i++) {
    if(d[i] == 'R'){
      if(d[i + 1] == 'R') ans++;
      else if(d[i + 1] == 'L') ans += 2;
      else if(d[i + 1] == 'S') ans++;
    }else if(d[i] == 'L'){
      if(d[i + 1] == 'L') ans++;
    }else if(d[i] == 'S'){
      if(d[i + 1] == 'L') ans++;
    }
  }
  return ans;
};

总结

  • 相撞的问题,很远的两个车,方向相反也会相撞,不要只考虑相邻的两个车,会出错