【问题标题】:Finding matches in two bags在两个袋子里找火柴
【发布时间】:2012-02-12 07:21:29
【问题描述】:

这是面试问题之一,我想知道我是否做得对,并想知道我的解决方案是否是最有效的解决方案。 O(n log n)

给定一袋螺母和一袋螺栓,它们在一个袋子中的尺寸不同,但在另一个袋子中正好有一个匹配项,给出一个快速算法来找到所有匹配项。

由于 2 个袋子之间总是匹配的,所以我说会有相同数量的螺母和相同数量的螺栓。设号码为n

我会首先对每个袋子中的组件进行分类,每个组件的重量,这是可能的,因为它们在袋子中都有不同的尺寸。使用归并排序,将会有 O(n log n) 的时间复杂度。

接下来,将 2 个袋子中的每个组件从最轻到最重进行匹配将是一个简单的过程。

我想知道这是否是正确的解决方案,以及是否有其他有趣的方法可以解决这个问题。

【问题讨论】:

  • 是的,看起来你成功了。

标签: algorithm


【解决方案1】:

即使您无法直接比较两个螺母或两个螺栓,在 O(nlgn) 中也有解决此问题的方法。那是在不使用秤的情况下,或者如果重量差异太小而无法观察。

它通过应用随机快速排序的小变化来工作,如下所示:

  1. 随机选择一个螺栓 b.
  2. 将螺栓 b 与所有螺母进行比较,将螺母分为尺寸小于 b 和大于 b 的螺母。
  3. 现在我们还必须将螺栓也分成两半,我们无法将螺栓与螺栓进行比较。但是现在我们知道了与 b 匹配的螺母 n 是什么。因此,我们将 n 与所有螺栓进行比较,将它们划分为大小小于 n 和大于 n 的螺栓。
  4. 问题的其余部分直接来自随机快速排序,将相同的步骤应用于螺母和螺栓的小于和大于分区。

【讨论】:

  • nLog(n) 是最好和平均的情况,插入排序是最坏的情况 o(n^2)
【解决方案2】:

标准解决方案是将坚果袋放入散列(或 HashMap、字典或您选择的任何语言)中,然后使用散列查找遍历另一个袋子以查找匹配项。

该算法的平均性能为 O(n),其常数比您的排序/二分搜索变体更好。

【讨论】:

  • 这看起来更好,假设您可以找到一个适用于螺母和螺栓的哈希函数。我的意思是,match(bolt,nut) -> boolean 是微不足道的 - O(1) - 但是您将使用哪个属性进行散列,使得 f(nut) == g(bolt) for all nuts and bolts?
【解决方案3】:

假设您没有精确的尺寸测量值,并且您只能通过尝试查看某物是否太大、太小或完全正确,这需要您进行排序的额外步骤——这可能是通过随机螺母,与每个螺栓进行比较并分类成更小,更大的桩,然后取出一个螺栓并用它对螺母进行分类(修改后的快速排序......请记住,您必须处理如何选择一个螺母或螺栓与桩变小时进行比较,以确保您使用的是合理的枢轴)。

由于问题没有告诉您螺母和螺栓标有尺寸,或者您有某种方法可以测量螺母和螺栓的尺寸,因此很难使用哈希表来解决这个问题,或者甚至是常规的比较排序。

【讨论】:

  • 但是,如果螺栓的变化超过一个比例(例如,周长、螺纹高度和螺纹间距),您无法使用枢轴轻松地将它们分开......我猜一般情况下,考虑到所有因素,您不能在少于O(n^2)
  • (PS 在有人指出之前,我知道这是从 OP 规范推断出来的;我仍然认为这个解决方案是给定情况下的最佳解决方案)
  • @mgibsonbr:回复:“如果螺栓在多个尺度上变化(例如,周长、螺纹高度和螺纹间距),您不能使用枢轴轻松划分它们”:那不是真的。这些“比例”中的每一个都很容易比较,因此您可以使用字典顺序对所有两个螺栓进行排序(首先比较周长;如果周长相等,则回退到螺纹高度;如果仍然相等,则回退到螺纹间距)。
【解决方案4】:

就复杂性而言,这对我来说似乎是最好的解决方案。

另一种方法是仅对其中一个袋子进行排序,然后使用二分搜索尝试将螺栓与螺母匹配(从排序列表中删除该对)。仍然是O(n log n),但第二部分略有优化,因为我们在比赛结束后删除了每一对,最坏的情况是:log n + log n-1 + log n-2 ... 1 = (n log n)/2

【讨论】:

  • @AlexD 看到 bdares 的回答:P
【解决方案5】:

多带两袋。说左右包。现在取出每个螺母并与每个螺栓进行比较。如果螺栓小,则将其放入左袋中,大则放入右袋,适合然后将其放好。现在拿下一个坚果,和之前拿的坚果比较,如果它更小,那么我们只需要检查左边袋子里的那些坚果,否则检查右边袋子里的那些。以这种方式继续。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    相关资源
    最近更新 更多