Given n coins, some of which are heavier, find the number of heavy coins?
给定n个硬币,其中一些更重,使用O(对数2 N)重量计算重硬币数量的算法。注意,所有的重硬币都有相同的重量,所有的轻硬币也有相同的重量。
给你一个天平,你可以用它比较两个分开的硬币子集的重量。请注意,平衡仅指示哪个子集更重,或者它们是否具有相等的权重,而不是绝对权重。
- 也许你可以更具体一点,在最后一句话里你说有同样的重量?
- 这意味着有两个重量,"重"和"轻"。
- 你知道每枚轻硬币和每枚重硬币的重量比吗?"称"是否表示一组硬币的重量,是否表示一组硬币比另一组硬币重多少,或者只是表示一组硬币比另一组硬币重?在不知道"称重"所提供的信息的情况下,没有足够的信息来回答这个问题。
- @马克班尼斯特,你得到一个平衡,你可以使用它比较两个不相交的硬币子集的重量。请注意,平衡仅指示哪个子集更重,或者它们是否具有相等的权重,而不是绝对权重。
- 这看起来像是家庭作业问题或面试问题。如果你分享你的思维过程并缩小到特定的问题范围,你很可能会得到更好的回答,或者在此时重新开始。
- @韦伯实际上是去年决赛中的一个问题。明天我有算法期末考试,所以我在找这个问题的答案。
我不会把全部答案都给你,但我会帮你把它分解。
找一个O(log(n))算法来找到一个重硬币。
找到一个O(log(n))算法,将一个集合分成两个集合,每个集合的重计数和轻计数数量相等,加上最多两个剩余部分(当没有相等数量的剩余部分时)。
结合算法1和2。
提示:
- 算法1独立于算法2。
- O(log(n))提示二进制搜索
- 你怎么可能最终得到两个O(log(n))算法的O(log^2(n))?
- 在O(log n)中找到一个重的硬币,我们可以把所有的硬币分成两半,然后选择较重的那一半,然后再把它分成两半,再选择较重的那部分,等等。这是正确的吗?这就像二进制搜索。
- 这是要点,但你也需要能够说出什么时候的一半有同等的重量,以及如何处理案件,其中的硬币数量不可等分。
- 你有什么特别的想法吗?或者你给出了一个只是猜测的算法?我很肯定,用一个类似于证明排序是欧米伽(nlogn)问题的证据来证明O(n)是不可能做得更好的。在这里,你有一个子集的硬币{c | c is heavy},你需要找到。但是请注意,可能的子集数量为2^n。每个比较操作都可以将你的候选人名单缩小一半。因此,比较需求的总数是Omega(log(2^n))=Omega(n)。
- @阿米特,我们没有被要求找到重硬币的子集,只是它的基数。如果您接受上述2是可能的,那么重硬币的数量是同等重量一侧的重硬币数量的两倍(加上分裂后的一个或两个剩余部分中的任何重硬币)。另一面可能会被丢弃,因为我们并没有试图真正隔离重硬币,而且其中的重硬币数量与另一面相同。所以每一个操作都将桩切成两半。有lg n操作的lgn迭代(加上lgn,找到一个初始重值,与剩余值进行比较)。
- 提示2。把那堆东西分成两半。如果两半的重量相同,那么假设没有。定义从左向右和从右向左旋转硬币的顺序。如果你一次做一对,就会达到天平要么平衡要么向另一个方向倾斜的程度。根据您的顺序,执行二进制搜索,而不是在发生这种情况时进行查找。