寻找旧面试技巧的新思路

时间:2011-10-18 13:31:35

标签: algorithm random probability

最初的问题是:

描述一种输出掷骰(从1到6的随机数)的算法,给出一个输出抛硬币(从1到2的随机数)的函数。每种可能的结果应该同样可能。

这个问题最受欢迎的答案是:

翻转硬币三次,并使用三个硬币翻转作为三位数的位。如果数字在1到6的范围内,则输出数字。否则,重复一遍。

我的问题是:

关于Stack Overflow的大多数讨论都有上述风格。我也搜索了互联网,发现其他口味的答案很多,他们没有明确地深入研究。有人可以就这个问题分享一两个不同的想法吗?

3 个答案:

答案 0 :(得分:3)

“折腾3次并丢弃,如果110或111”算法有一点小改进。丢弃110或111是浪费,因为你浪费了一个你可以重用的完美的熵。弹出其中一个值后,您只需要折腾两次并从映射{110-> tails,111-> head}获得第三次折腾的值。 110和111都是同样可能的,所以你不会以这种方式引入任何偏见。

在伪代码中:

bit0 = toss()
while True:
   bit1 = toss()
   bit2 = toss()
   if bit1,bit2,bit3 give i such that 0<=i<=5 then 
      return i+1
   else
      bit0 = bit3 // the reuse happens here

此处预期的投掷数为1 + 2 * expected_number_of_loop_executions = 1 + 2 * 8/6 = 11/3

答案 1 :(得分:2)

如果你只是想要其他选择,不一定是好选择,那么如何:

  1. 为每个可能的输出值翻转一枚硬币。
  2. 如果有一个或多个头,则丢弃所有可能的尾部值。
  3. 如果您只剩下一个值,请停止。其他转到1。
  4. 我怀疑它会比你描述的方法有更高的预期硬币投掷次数,而且根本没有任何优势。

    一般来说,我认为这就是使用随机数的其他可能方法的原因。它们不太好。

答案 2 :(得分:1)

  1. 翻转5个硬币。如果他们都是头或全尾,你的答案是1.如果只有一个头或一个尾,继续下一步。如果有多个头部和多个尾部,请重复此步骤(包括重新盖上硬币)。

  2. 翻转4个硬币。如果他们都是头或全尾,你的答案是2.如果只有一个头或一个尾,继续下一步。如果有两个头和两个尾巴,请重复此步骤(包括重新盖上硬币)。

  3. 翻转3个硬币。如果他们都是头或全尾,你的答案是3.否则,继续下一步

  4. 翻转2个硬币。如果它们都是头,你的答案是4.如果它们都是尾巴,重复这一步(包括重新盖上硬币)。否则,继续下一步。

  5. 翻转1枚硬币。如果它是头,你的答案是5.如果它是尾巴,你的答案是6。