Java 寻找n/2元素的数字流和最佳空间复杂度

Java 寻找n/2元素的数字流和最佳空间复杂度,java,algorithm,data-structures,Java,Algorithm,Data Structures,我试图解决这个问题,其中给出长度不超过M的数字流。您不知道流的确切长度,但可以确定它不会超过M。在流的末尾,您必须告诉流的N/2th元素,因为N元素出现在流中。解决此问题的最佳空间复杂度是什么 我的解决方案: 我想我们可以排一个大小为m/2的队列,推两个元素,然后弹出一个元素,一直到 溪流已过。n/2th将位于队列的最前面。时间复杂度在任何情况下都是最小的O(n),但对于这种方法,空间复杂度是m/2。。有更好的解决方案吗?我希望很明显,您至少需要N/2内存分配(除非您可以重新迭代steam,再次

我试图解决这个问题,其中给出长度不超过
M
的数字流。您不知道流的确切长度,但可以确定它不会超过
M
。在流的末尾,您必须告诉流的
N/2th
元素,因为
N
元素出现在流中。解决此问题的最佳空间复杂度是什么

我的解决方案: 我想我们可以排一个大小为
m/2
的队列,推两个元素,然后弹出一个元素,一直到
溪流已过。
n/2th
将位于队列的最前面。时间复杂度在任何情况下都是最小的
O(n)
,但对于这种方法,空间复杂度是
m/2
。。有更好的解决方案吗?

我希望很明显,您至少需要
N/2
内存分配(除非您可以重新迭代steam,再次读取相同的数据)。您的算法使用
M/2
,因为
N
M
的上界,所以选择哪一个似乎无关紧要,因为
N
可以上升到
M

但这不一定。如果您认为<代码> n>代码>小于<代码> m <代码>(例如<代码> n=5 < /代码>和<代码> m=1 000×000 < /COD>),则会浪费大量资源。

我建议使用一些动态增长数组结构,比如
ArrayList
,但这不利于删除第一个元素

结论:你可以同时拥有
O(N)
时间和内存复杂性,而且你再也没有比这更好的了


关于
ArrayList
的友好编辑:将元素添加到
ArrayList
是在“摊销固定时间”中,因此添加N个项目在时间上是O(N)。然而,删除它们是线性的(根据JavaDoc),因此您可以在时间和空间上明确地得到O(N),但是只有在不删除任何内容的情况下。如果你删除了,你会得到空间中的O(N)(O(N/2)=O(N)),但是你的时间复杂度会增加。

我希望很明显,你至少需要
N/2
内存分配(除非你可以在steam中重新迭代,再次读取相同的数据)。您的算法使用
M/2
,因为
N
M
的上界,所以选择哪一个似乎无关紧要,因为
N
可以上升到
M

但这不一定。如果您认为<代码> n>代码>小于<代码> m <代码>(例如<代码> n=5 < /代码>和<代码> m=1 000×000 < /COD>),则会浪费大量资源。

我建议使用一些动态增长数组结构,比如
ArrayList
,但这不利于删除第一个元素

结论:你可以同时拥有
O(N)
时间和内存复杂性,而且你再也没有比这更好的了


关于
ArrayList
的友好编辑:将元素添加到
ArrayList
是在“摊销固定时间”中,因此添加N个项目在时间上是O(N)。然而,删除它们是线性的(根据JavaDoc),因此您可以在时间和空间上明确地得到O(N),但是只有在不删除任何内容的情况下。如果你移除,你会得到空间中的O(N)(O(N/2)=O(N)),但你的时间复杂度会增加。

你知道“乌龟兔”算法吗?从两个指向输入开头的指针开始。然后在每一步中,兔子前进两步,乌龟前进一步。当兔子到达输入端时,乌龟处于中点。这是O(n)时间,因为它访问输入的每个元素一次,而O(1)空间,因为不管输入的大小,它只保留两个指针。

你知道“龟兔”算法吗?从两个指向输入开头的指针开始。然后在每一步中,兔子前进两步,乌龟前进一步。当兔子到达输入端时,乌龟处于中点。这是O(n)时间,因为它访问输入的每个元素一次;O(1)空间,因为不管输入的大小,它只保留两个指针。

但是如果兔子在项目100,乌龟在项目50。当兔子转到102时,项目51最好在内存中。因此,他必须在内存中至少保留n/2项。我们不知道流的性质。我假设流是持久的。当然,这将适用于持久流。但是,如果我们假设一个网络流,或者类似磁带的东西,那么这种方法就不起作用了。事实上,这个问题很有趣,因为OP没有说“数组”或“列表”。在一般情况下,给定一条溪流,你会有一次机会。但是如果兔子在第100项,乌龟在第50项。当兔子转到102时,项目51最好在内存中。因此,他必须在内存中至少保留n/2项。我们不知道流的性质。我假设流是持久的。当然,这将适用于持久流。但是,如果我们假设一个网络流,或者类似磁带的东西,那么这种方法就不起作用了。事实上,这个问题很有趣,因为OP没有说“数组”或“列表”。在一般情况下,给定一个流,您只需要一次机会。这是一个持久流(例如,一个文件),还是类似于一个网络流,如果您不存储某个项目,您只有一次机会看到它?这是一个持久流(例如,一个文件),或者类似于一个网络流,如果你不存储一个项目,你只有一次机会看到它?@ErickG.Hagstrom:只有当它是一个持久流时,这才是正确的。@JimMischel很好。您必须存储所有的o