这可能是一个有效的解决方案,但我没有看到它。 我不知道如何解释我的问题但是这里......
假设我们有一个带有n个整数的数组,例如{3,2,0,5,0,4,1,9,7,3}。 我们想要做的是找到具有“最大最小值”的5个连续元素的范围...... 此示例中的解决方案是此部分{3,2,0,5,0, 4,1,9,7,3 },其中 1 为最大值最小。
使用O(n ^ 2)很容易,但必须有更好的方法。它是什么?
答案 0 :(得分:2)
如果您的字面意思是五个连续元素,那么您只需要保留源数组的排序窗口。 说你有: {3,2,0,5,0,1,0,4,1,9,7,3}
首先,你得到五个元素并排序:
{ 3,2,0,5,0, 1,0,1,9,7,3} {0,0,2,3,5} - 已排序。
这里最小值是排序序列的第一个元素。
然后你需要向前推进一步,你看到新元素 1 和旧元素 3 ,你需要找到并替换 1 ,然后将数组返回到排序状态。实际上你不需要对它运行排序算法,但你可以因为只有一个元素位于错误的位置(本例中 1 )。但即使是冒泡排序也会在线性时间内完成。
{3, 2,0,5,0,1, 0,4,1,9,7,3}
{0,0,1,2,5}
然后新的最小值再次成为第一个元素。
然后一次又一次地推进并将排序序列的第一个元素与最小值进行比较并记住它和子序列。
时间复杂度为O(n)。
答案 1 :(得分:1)
你不能使用5个元素的循环缓冲区,在数组上运行并将最新的元素添加到缓冲区(从而替换最旧的元素)并在缓冲区中搜索最小的数字?将带有偏移量的变量保存到给出最小最小值的数组中。
我认为那似乎是O(n * 5 * log(5))= O(n)。
编辑:我看到unkulunkulu的建议与我完全相同:)。
答案 2 :(得分:1)
使用平衡二叉搜索树而不是线性缓冲区,获得复杂度O(n log m)是微不足道的。
答案 3 :(得分:1)
您可以在O(n)
中为任意k
个连续元素执行此操作。使用deque。
对于每个元素x
:
pop elements from the back of the deque that are larger than x
if the front of the deque is more than k positions old, discard it
push x at the end of the deque
at each step, the front of the deque will give you the minimum of your
current k-element window. Compare it with your global maximum and update if needed.
由于每个元素最多只能从双端队列推送和弹出一次,因此O(n)
。
deque数据结构可以使用与初始序列大小相同的数组实现,获取O(n)
内存使用量,也可以使用实际从内存中删除所需元素的链接列表来实现,获取O(k)
内存使用情况。