你想知道为什么这个答案会被接受是正确的。这个答案明显具有O(n)空间复杂度。你分配了一些数据,它与n成正比增长,使得它的空间复杂度为O(n)。无论是什么评判你的程序都是错误地接受它。可能评判者之所以接受你的分数是因为你使用的字节数少于A分配的字节数,但这只是猜测。
编辑:下面的代码实际上不是解决问题的方法。这是一个类似于上述问题的简单问题的解决方案。下面的解决方案忽略了必须只读取流的约束条件。经过一些研究,发现这个问题是一系列类似问题的非常困难的版本,类型为“在1到n之间给定一系列数字,找到重复/缺失的数字”。如果只有一个数字重复,并且只需要O(n)的时间,可以使用如上所述的bool向量。如果只有一个数字重复,但受到常数空间的限制,可以实现这个
solution,其中我们使用高斯公式来找到从1到n的整数之和,并将其从数组的总和中减去。如果数组有两个缺失的数字,并且你受到常数时间的限制,你可以实现这个
solution,其中我们使用数组的和与积创建一个方程组,可以在O(n)时间内用O(1)空间解决。
要解决上述提出的问题,看起来需要实现类似于这个
monstrosity的东西。
这里有一个在其限制内解决此问题的方法:
你可以像这样做:
#include<vector>
#include<iostream>
int repeating(std::vector<int>& arr)
{
for (int i = 0; i < arr.size(); i++)
{
if (arr[abs(arr[i])] >= 0)
arr[abs(arr[i])] = -arr[abs(arr[i])];
else {
return abs(arr[i]);
}
}
}
int main()
{
std::vector<int> v{1,2,3,4,5,1};
std::cout<<repeating(v)<<std::endl;
std::cout<<sizeof(v)*sizeof(v[0])<<std::endl;
return 0;
}
上述程序使用输入数组本身来跟踪重复项。对于每个索引i,数组评估arr[i]。数组将arr(arr[i])设置为负数。否定一个值是一种容易可逆的操作(只需取元素的绝对值),因此它可以用于标记数组的索引,而不破坏数据的完整性。如果您遇到这样的索引,即arr[abs(arr[i])]为负数,则知道您之前在数组中看到过abs(arr[i]))。这使用O(1)空间复杂度,遍历一次数组,并且可以修改以返回任何或所有重复数字。
O(n)
的额外空间。它不少于O(n)
。 - François Andrieuxstd::set
是否有任何大小保证,但它的大小至少与其元素的总和一样大。如果您需要存储最多n
个元素,则您的内存需求至少为O(n)
。 - François AndrieuxO(n)
和O(n-1)
是相同的复杂度。而O(n)
是一个下限,std::set
可能会占用更多的内存,据我所知标准没有提供任何保证。 - François Andrieux