Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在O(1)空间的数组中找到重复元素的证明_Algorithm_Data Structures - Fatal编程技术网

Algorithm 在O(1)空间的数组中找到重复元素的证明

Algorithm 在O(1)空间的数组中找到重复元素的证明,algorithm,data-structures,Algorithm,Data Structures,假设数组的大小为n+2,并且输入元素限制在范围(1,n)内,我遇到了一种使用求反(方法5,)来解决使用O(1)空间查找重复项的问题的方法。然而,我并不完全相信这是为什么,有人能帮我证明一下吗?要知道这个算法是有效的,首先用额外的空间来解决它可能会有帮助 计数事件 创建一个名为count的数组,索引为1到n,初始化为全零。这将跟踪您在输入数组中遇到特定值的频率。然后检查哪些计数大于1。因此,算法(伪代码)非常简单: count:=数组(n) #初始化计数: 对于i:=1到n: 计数[i]=0 #开

假设数组的大小为n+2,并且输入元素限制在范围(1,n)内,我遇到了一种使用求反(方法5,)来解决使用O(1)空间查找重复项的问题的方法。然而,我并不完全相信这是为什么,有人能帮我证明一下吗?

要知道这个算法是有效的,首先用额外的空间来解决它可能会有帮助

计数事件 创建一个名为
count
的数组,索引为1到n,初始化为全零。这将跟踪您在输入数组中遇到特定值的频率。然后检查哪些计数大于1。因此,算法(伪代码)非常简单:

count:=数组(n)
#初始化计数:
对于i:=1到n:
计数[i]=0
#开始计数:
对于A中的值:
计数[值]:=计数[值]+1
#提取非唯一性
重复项:=数组()
对于i:=1到n:
如果计数[i]>1:
重复。追加(i)
返回副本
标记事件 我们可以观察到,当我们将某个计数从1增加到2时,我们已经可以检测到重复。所以我们不需要存储2的计数。我们可以将计数保留为1,然后将值添加到输出中。第一次遇到值时,对应的0将变为1,下一次我们将看到已经有1,并得出结论,我们有一个重复的值(并保持1不变)。这样我们只需要存储两种值(0或1)。我们将为这个辅助数组使用一个更合适的名称:它可以命名为
found
,而不是
count

found:=数组(n)
#初始化:
对于i:=1到n:
找到[i]:=0
#循环并收集重复项:
重复项:=数组()
对于A中的值:
如果找到[值]==0:
找到[值]:=1
else:#以前已遇到此值
重复项。追加(值)
返回副本
将数据打包在一起 仅存储0或1实际上只不过是存储一位而已。为了去掉辅助空间,我们可以说,在输入数组的每个值中肯定有一个未使用的位可用:给定的输入值都在1..n范围内,因此它们是正的,因此不使用符号位。我们可以在那里“隐藏”我们的比特信息

要使其工作,我们必须确保该位的使用不会干扰输入值的存储

因此,当我们从输入数组中读取值时,必须确保忽略该符号位(通过获取绝对值)。当我们想读/写额外的位时,我们应该确保不干扰原始(正)输入值。位和值应该共存,而不会相互影响。您可以将其视为包含2个数据的元组:一个位和一个介于1..n之间的数字。他们没有关系

它本质上与上面的算法没有什么不同(找到了
)。唯一的区别是两个(不相关的)数据被打包成一个值

我希望当你这样看的时候,算法会变得清晰

评论
对该算法的一个批评是,它确实使用了额外的空间。假设您的输入由无符号字节组成,n是255,那么实际上就没有多余的空间了。

方法5适用于基于1的数组。假设数组是A={2.3.1.3}你读取第一个值(2),交换A[2]的符号,使数组现在是{2.-3.1.3}你读取下一个值(3),交换A[3]的符号,使数组现在是{2.-3.-1.3}你读取下一个值(1),交换A[1]的符号,使数组现在是{-2.-3.-1.3}读取下一个值(3)并交换[3]的符号,使数组现在为{-2.-3.+1.3},完成步骤1。现在看看前n个值的符号:如果负数只改变了一次,如果正数则改变了两次(dup),请不要将重要信息放在场外链接中,而是将相关信息包含在问题中。你的问题应该是完全独立的,可以回答,不需要任何链接。请确保这样做时不侵犯任何版权。