SWE · OA / Coding

Meta 最近已发公交:严格早于当前与当日边界

寻找当天严格早于current的最近发车,返回已过分钟数,排除刚好同刻班次。

题目重点:寻找当天严格早于current的最近发车,返回已过分钟数,排除刚好同刻班次。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练HH:MM同一日24小时制,departure顺序不保证;与current相同不算已发,之前没有返回−1,不自动回到昨天末班。

解题路线

  1. 把时间转hour×60+minute,避免按字符串/小时单独比较。格式固定两位,范围0..23/0..59校验。
  2. 扫描保留最大且<now的departure,最后now−last。不需要全列表排序,仅一次最大值更新。
  3. 等于now必须排除;业务若按开始发车即算已走是≤版本,不能偷偷替换。
  4. 没有输入日期就无证据推断昨天发车;重复departure不影响max,空列表−1。独立测试使用datetime时间差。

手动走一遍

11:20、15:00与current14:30,最近11:20,过190分钟;加入14:30也仍190。current00:00时当日之前无班次,列表23:59也返回−1。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def elapsed_since_bus(departures,current):
    """Same calendar day HH:MM, equality excluded; no previous-day wrap."""
    def minutes(text):
        if len(text)!=5 or text[2]!=':' or any(not '0'<=ch<='9' for ch in text[:2]+text[3:]):raise ValueError('HH:MM required')
        hour=int(text[:2]);minute=int(text[3:])
        if not 0<=hour<24 or not 0<=minute<60:raise ValueError('time outside day')
        return hour*60+minute
    now=minutes(current);last=None
    for departure in departures:
        t=minutes(departure)
        if t<now and (last is None or t>last):last=t
    return now-last if last is not None else -1

复杂度

O(D)时间/O(1)辅助空间,解析固定5字符。很多查询且已排序可预转分钟后每次二分O(logD),单次不必预排序。

易错点与追问

容易失分的边界

  • ≤把同刻班次返回0,违背严格过去。
  • 同日23:59被当昨天,无日期支持。

继续深挖

  • 有timezone/date时,夏令时重复或缺失分钟怎样处理?
  • bisect_left定位严格早班次,与bisect_right有何区别?
✓已复制微信号!