【问题标题】:Algorithm question: Finding the cheapest flight算法题:寻找最便宜的航班
【发布时间】:2021-12-27 21:26:37
【问题描述】:

我最近在一家公司面试(以 M 开头,以 A 结尾)问了我这个问题。还在练习我的算法,所以我希望有人能帮助我理解如何解决这个问题,以及这些类型的问题。

问题:

给你 2 个数组。例如:

D = [10,7,13,12,4]
R = [5,12,7,10,12]

D表示城市A到城市B的航班出发价格。 R 表示从城市B 到城市A 的航班返回价格。查找城市A 和城市B 之间往返航班的最低费用。例如,示例中的最小值为D[1] + R[2]

(只能乘坐与出发航班相同或更高索引的回程航班)

棘手的部分是,很明显,你必须在返回之前离开。

天真的方法只是结合了所有可能性的双 for 循环。但是,我知道有更好的方法,但我无法绕过它。我相信我们想要创建某种临时数组,目前为止的最小值或类似的东西......

感谢阅读。

【问题讨论】:

  • 查找图表和最短路径算法
  • 谢谢。我最初的想法也是图表,但面试官实际上告诉我这不是图表问题。
  • 这是否意味着如果您乘坐D[i] 航班,您可以使用回程航班R[i] 及以上或R[i+1] 及以上?
  • 没错。可以访问R[i],以及所有的R[i+1...i+2...i+n]
  • 这是一个棘手的问题,我也花了一些时间来理解它。唯一的限制是,如果您选择 D 中的索引 i,则无法访问 R 中的 i-k。您只能访问 R 中的 i...i+k。(因为您不能在离开前返回)。允许当天返回。

标签: python arrays algorithm


【解决方案1】:

我对@user1984 的解决方案非常满意。但如果你真的想给他们留下深刻印象:

from itertools import accumulate

monoQ = list(accumulate(reversed(R), min))
monoQ.reverse()

best = min(d + r for d, r in zip(D, monoQ))

大多数人都熟悉返回(1, 3, 6, 10, 15)list(accumulate((1, 2, 3, 4 5), operator.add)),但使用min 会使结果成为迄今为止看到的最小元素。既然要从这里到最后的最小元素,就得把列表倒过来,累加,然后再倒过来。


由于这是在其他答案之一的讨论中出现的,因此可以将其重写为 O(1) 空间。

best = min(d + r for d, r in zip(reversed(D), accumulate(reversed(R), min)))

这有点老套,除非特别要求您提供 O(1) 空间解决方案,否则我不会推荐它。

不幸的是,您必须使用reverse(D) 并从列表末尾开始工作,而不是reverse(accumulate(...)),因为您不能将reverse 应用于累积。 zipreversedaccumulate 都返回迭代器,而不是列表或元组。

【讨论】:

  • 非常有趣!谢谢!
  • 确实如此。很有意思。钛白粉。如此优雅。
  • 非常干净的解决方案,不知道像这样使用accumulate :D
【解决方案2】:

从返回价格数组R 中创建一个单声道队列/堆栈,然后您可以在O(n) 中解决它,其中nD 的长度。

R = [5, 12, 9, 10, 12] => [5, 9, 9, 10, 12]

正如您在每个步骤中看到的那样,我们可以在索引i 及以上位置获得最便宜的回程航班。

现在,遍历 D 的元素并查看 monoQ 中的索引。由于monoQ 处的索引是Ri 及更高版本中可能的最小索引,因此您现在不能做得更好。

在代码中:

D = [10,7,15,12,4]
R = [5,12,9,10,12]

monoQ = [0]*len(R)
monoQ[-1] = R[-1]

for i in range(len(R)-2, -1, -1):
  monoQ[i] = min(monoQ[i+1], R[i])

best = R[0]+D[0]
for i, el in enumerate(D):
  best = min(best, D[i]+monoQ[i])
print(best)

【讨论】:

  • 这是一个很好的解决方案,谢谢!
  • @user1984 它可以在 O(1) 额外空间内完成,不需要 monoQ 只需使用 R(for min array)
猜你喜欢
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多