Algorithm 棘手的算法问题

Algorithm 棘手的算法问题,algorithm,puzzle,divide-and-conquer,Algorithm,Puzzle,Divide And Conquer,可能重复: 输入:未排序数组A[1,…,n],它包含范围0,…,n中除一个外的所有整数 问题是确定O(n)时间内缺少的整数。A的每个元素都是 以二进制表示,唯一可用的操作是函数位(i,j),它 返回[i]的第j位的值,并采用恒定时间 有什么想法吗?我认为某种分而治之的算法是合适的,但我想不出我到底应该做什么。提前谢谢 这是一个数学性质,1和n之间的数字之和,其中n是n(n+1)/2。您可以在10中看到这一点: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 =

可能重复:

输入:未排序数组A[1,…,n],它包含范围0,…,n中除一个外的所有整数

问题是确定O(n)时间内缺少的整数。A的每个元素都是 以二进制表示,唯一可用的操作是函数位(i,j),它 返回[i]的第j位的值,并采用恒定时间


有什么想法吗?我认为某种分而治之的算法是合适的,但我想不出我到底应该做什么。提前谢谢

这是一个数学性质,
1
n
之间的数字之和,其中
n
n(n+1)/2
。您可以在
10
中看到这一点:

  1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
= (1+10) + (2+9) + (3+8) +(4+7) + (5+6)
= 11 + 11 + 11 + 11 + 11
= 55
因此,通过扩展,它是从
0
n
的数字之和,因为您只是将0添加到它。所以你要做的就是把所有的数字加起来并保持一个计数,然后用这个公式来计算出缺失的一个

比如说:

count = 0
sum = 0
foreach num in list:
    sum = sum + num
    count = count + 1
missing = count * (count+1) / 2 - sum

使用
位(i,j)
获取数字是一件棘手的事情,因此您必须单独提取位并将其转换为实际数字进行求和。

这是一个棘手的问题,因为使用bit方法只需要为每个数字循环每个位,这意味着它将自动变为O(n*j)其中j是表示n的位数


我想paxdiablo已经知道了,假设允许您使用不使用位方法的解决方案。

您可以使用XOR运算符,因为它比加法更快。因为您可以访问每一位,所以这里将执行按位异或。 这里使用的原理是(A XOR B XOR A)=B

例如:(1xor2xor3)XOR(1xor2)=3


如果位(i,j)是唯一可用的操作,您建议如何实现分治算法?@a.雷克斯:您链接的可能的重复对指令没有相同的限制,因此我认为它不一定是重复。这不是重复。在这个问题中,您只需要读取输入A的n个log n位中的O(n)。如果这是唯一的约束(即,如果位(i,j)之外的操作是自由的,那么您仍然可以使用分治算法来解决它,比如:算法的注释大小描述是计算奇偶数的数量,检查哪个计数与从0…n中得到的计数不匹配,并在丢弃最低位后对输入的那一半进行递归。这不是的重复,paxdiablo的答案是错误的,Reid解释道。里德的算法是O(n),如果你在计算的时候在每一半中保留一个元素的列表。事实上,这很漂亮,+1。你不能肯定XOR会比加法快,但它是对使用XOR查找单例的大多数变体中的两个/一个(例如,
91918282736455
)的巧妙修改。XOR永远不会比加法慢。。。原因:除此之外,还有一个携带位需要一个全加器加上一个步骤……在现代体系结构中,它被使用具有几乎相同性能的并行加法器消除(xor在此操作中使用1个较小的门)。对于1到n的xor,有一个O(1)公式。XOR也避免了溢出问题。Neil,从技术上讲,这仍然是
O(n)
,因为
j
是一个常量。实际上,j是常量,因为整数或long的长度总是相同的,但是j的有效位以n*2递增1,其中n>0。更像O(logn)。它读取A的所有n个logn位,因此需要n个logn时间。@Reid:不,它根本不是n个logn。不能同时使用n表示位数和整数数。整数中的位数是恒定的,因此它实际上是
O(32n)
(对于32位数字),这与
O(n)
完全相同。我很确定,当OP写入“整数”时,它们的意思是“整数”,而不是“小于2^32的整数”。否则,只有有限多个可能的输入,所以谈论渐近运行时根本没有意义。很明显,一个以位为单位的实际数学整数的长度并不是恒定的。我很确定整数意味着一个固定宽度的整数,即32位或1024位,而不是一个基于整数值的可变长度整数。这是因为这是一个编程问答网站,固定宽度架构的数量远远超过可变宽度架构的数量:-)无论固定宽度是32还是任何其他常数,都不重要,它仍然是一个常数。我可能错了,但基于证据的优势,我对此表示怀疑。如果您想要澄清,请随时询问OP。如果结果证明我错了,我将删除或编辑以修复。
for i=0 to n
{
Total=Total XOR i
}

foreach element in A
{
Total=Total XOR element
}