我正在尝试解决以下难题:
Given a stream of numbers (only 1 iteration over them is allowed) in which all numbers appear 3 times, but 1 number appear only 2 times, find this number, using O(1) memory.
我开始认为,如果所有数字都出现2次,而且只有1次出现,我可以在所有数字之间使用xor
操作,结果将是隐身号码。
所以我想扩展这个想法来解决难题。我需要的只是类似xor的函数(或运算符),它将在第三个应用中产生0:
SEED xor3 X xor3 X xor3 X = SEED
X xor3 Y xor3 SEED xor3 X xor3 Y xor3 Y xor3 X = SEED
有关此类功能的任何想法吗?
答案 0 :(得分:3)
将XOR表示为以二进制表示的数字的每个位的总和(即2的基数),模2。
现在考虑一个由 tribits 0,1和2组成的数值系统。也就是说,它的基数为3.
操作符T
现在成为任何数字的操作,并分解为此基数。与在XOR中一样,您对这些位求和,但区别在于运算符T
以模3运行。
您可以轻松地显示任何a T a T a
a
为零。您还可以证明T
既可交换又关联。这是必要的,因为一般来说,你的序列会使数字混乱。
现在将其应用于您的数字列表。在操作结束时,输出将为b
,其中b = o T o
和o
是恰好两次出现的数字。
答案 1 :(得分:0)
对于更简单的案例(所有数字出现两次,一个数字出现一次)的解决方案有效,因为 xor 对每个位x进行操作
x xor x = 0 and 0 xor x = x
xor基本上是一个逐位求和模数2.你需要base-3等价物:将每个数字转换成一个base-3表示。然后对每个小数使用求和模3:
0 1 2
0 0 1 2
1 1 2 0
2 2 0 1
调用此操作xor3。现在你有每个十进制x:
x xor3 x xor3 x = 0 and 0 xor3 x = x
如果将其应用于所有数字,那么出现3次的所有值都将消失。结果是出现两次的x的x xor3 x。您需要按2模数3应用十进制除法。
我相信有更有效的方法来实现它。第一种情况下xor函数的优点在于xor是一种自然的base-2操作。那有什么实际应用吗?
答案 2 :(得分:0)
这种方法有点脆弱:如果前提条件(所有数字出现3次,除了出现两次的那个)打破算法将无法帮助你。
使用int-keys和int-values获取Map。然后遍历您的数字,每个数字x增加每个相应的值。如果x是新键,则将0作为起始值。
然后您可以轻松地分析它:遍历所有键并检查基数。所有键应该是三个,除了一个应该是两个键。这更加强大,我的直觉也表明它更快。