Algorithm 从给定数组构造具有一定约束的数组

Algorithm 从给定数组构造具有一定约束的数组,algorithm,Algorithm,给定一个由N个元素组成的数组,A[0..N-1]生成一个数组B,使得: B[i] = min (A[i], A[i+1], ..., A[i+K-1]). 数组B将正好有N-k+1个元素 时间复杂度应该比ON*k更好 我正在考虑使用minheap。。。但heapify会增加复杂性 暴力也在*k上 而且空间复杂度小于等于Ok 这里有一个例子 Input: A={ 2,1,3,2,5,7,1}, N=7,k=3 Output: B={1,1,2,2,1} 在ON而不是ON*k中执行此操作

给定一个由N个元素组成的数组,A[0..N-1]生成一个数组B,使得:

 B[i] = min (A[i], A[i+1], ..., A[i+K-1]). 
数组B将正好有N-k+1个元素

时间复杂度应该比ON*k更好

我正在考虑使用minheap。。。但heapify会增加复杂性 暴力也在*k上

而且空间复杂度小于等于Ok

这里有一个例子

Input: 
A={ 2,1,3,2,5,7,1}, N=7,k=3

Output:
B={1,1,2,2,1}

在ON而不是ON*k中执行此操作的关键是不要计算给定的公式 B[i]=mina[i],A[i+1],…,A[i+K-1],但增量更新

在每个步骤中,都有一个由K个排序条目组成的结果集

第一步:从前K个条目计算B[0],并将结果分配给B[0]

第一步: 计算B[1]您只需将A[i+K]添加到结果集中,然后从结果集中减去A[0],而不是再次添加K个条目

每个增量步骤: 因此,对于每个附加索引,您的结果集只有两次更新


总的来说,你有线性复杂度。

在ON而不是ON*k中这样做的关键是不要计算给定的公式 B[i]=mina[i],A[i+1],…,A[i+K-1],但增量更新

在每个步骤中,都有一个由K个排序条目组成的结果集

第一步:从前K个条目计算B[0],并将结果分配给B[0]

第一步: 计算B[1]您只需将A[i+K]添加到结果集中,然后从结果集中减去A[0],而不是再次添加K个条目

每个增量步骤: 因此,对于每个附加索引,您的结果集只有两次更新

总的来说,您具有线性复杂性。

步骤1 编写具有减少密钥功能的最小优先级队列。这意味着您可以通过指针转到节点,降低其值并更新堆优先级队列

操作减少_键为Ologk,k为优先级队列中的元素数

步骤2 考虑以下操作:

添加[i]:这包括向优先级队列添加[i],以及保留一个指向优先级队列中创建的节点的指针,例如C[i]。我是奥洛克

Remove A[i]:这意味着转到包含[i]到C[i]的节点,将其值减小到负无穷大,然后将其从堆的顶部移除。这也是奥洛克

步骤3 初始化优先级队列:将A的前k个元素添加到优先级队列中。这没关系

步骤4 按如下方式填充B的元素:

for i = 1 to n-k+1
    B[i] = pQ.top
    Remove A[i]
    Add A[i+k]
这部分在logk上

最终分析 此算法的总时间顺序为*logk。太空秩序还可以。这是优先级队列的k个节点和指向这些节点数组C的k个指针,如果简单地实现,这些节点数组C将打开。

步骤1 编写具有减少密钥功能的最小优先级队列。这意味着您可以通过指针转到节点,降低其值并更新堆优先级队列

操作减少_键为Ologk,k为优先级队列中的元素数

步骤2 考虑以下操作:

添加[i]:这包括向优先级队列添加[i],以及保留一个指向优先级队列中创建的节点的指针,例如C[i]。我是奥洛克

Remove A[i]:这意味着转到包含[i]到C[i]的节点,将其值减小到负无穷大,然后将其从堆的顶部移除。这也是奥洛克

步骤3 初始化优先级队列:将A的前k个元素添加到优先级队列中。这没关系

步骤4 按如下方式填充B的元素:

for i = 1 to n-k+1
    B[i] = pQ.top
    Remove A[i]
    Add A[i+k]
这部分在logk上

最终分析
此算法的总时间顺序为*logk。太空秩序还可以。这是优先级队列的k个节点和指向这些节点数组C的k个指针,如果简单地实现,这些节点数组C将打开。

要解决此问题,可以使用

将数组A中的前k个元素推送到该队列。然后继续从数组A填充队列,同时从中弹出元素并将最小值附加到数组B


时间复杂度正在上升。空间复杂度没有问题。

要解决此问题,可以使用

将数组A中的前k个元素推送到该队列。然后继续从数组A填充队列,同时从中弹出元素并将最小值附加到数组B


时间复杂度正在上升。空间复杂度是可以的。

从我前面的回答:,它有一个包含四种不同解决方案的列表

0通过结合两个经典面试问题,可以及时解决问题:

制作一个名为MaxStack的堆栈数据结构,它支持O1时间内的push、pop和max

这可以使用两个堆栈来完成,第二个堆栈包含迄今为止看到的最小值

使用堆栈对队列进行建模

这可以使用两个堆栈来完成。排队进入一个堆栈,而出队列来自另一个堆栈

为了这个问题 m、 我们基本上需要一个队列,它支持O1摊销时间内的排队、出列和最大值

我们通过对具有两个最大堆栈的队列建模,将上述两种方法结合起来

为了解决这个问题,我们对k个元素进行排队,查询max、dequeue、enqueue k+1个元素、查询max等。这将为每个k大小的子数组提供max

我相信还有其他解决办法

一,

我相信排队的想法可以简化。我们为每k维护一个队列和一个最大值。我们将一个新元素排队,并将所有不大于新元素的元素都除名

2维护两个新阵列,保持k的每个块的运行最大值,一个阵列用于左至右/右至左的一个方向

3使用锤子:及时预处理范围最大查询


上面的1个解决方案可能是最理想的。

来自我之前的答案:,其中列出了四种不同的解决方案

0通过结合两个经典面试问题,可以及时解决问题:

制作一个名为MaxStack的堆栈数据结构,它支持O1时间内的push、pop和max

这可以使用两个堆栈来完成,第二个堆栈包含迄今为止看到的最小值

使用堆栈对队列进行建模

这可以使用两个堆栈来完成。排队进入一个堆栈,而出队列来自另一个堆栈

对于这个问题,我们基本上需要一个队列,它支持O1摊销时间内的入、出和最大值

我们通过对具有两个最大堆栈的队列建模,将上述两种方法结合起来

为了解决这个问题,我们对k个元素进行排队,查询max、dequeue、enqueue k+1个元素、查询max等。这将为每个k大小的子数组提供max

我相信还有其他解决办法

一,

我相信排队的想法可以简化。我们为每k维护一个队列和一个最大值。我们将一个新元素排队,并将所有不大于新元素的元素都除名

2维护两个新阵列,保持k的每个块的运行最大值,一个阵列用于左至右/右至左的一个方向

3使用锤子:及时预处理范围最大查询



上述1种解决方案可能是最理想的。

问题是什么?ON*k是否正确?没有必要将should缩写为s'd。你把问题弄得难懂,这对你自己没有任何好处。不,On*k是不对的。此外,我已经更新了已理解的问题,并发布了答案问题是什么?ON*k是否正确?没有必要将should缩写为s'd。你把问题弄得难懂,这对你自己没有任何好处。不,On*k是不对的。此外,我还更新了已理解的问题,并发布了答案添加或插入。。。你怎么计算最小值?更新你的页面。我澄清了添加不是+而是添加到结果集,以及您是如何将新项插入O1中排序列表中查找项的排序列表中的?@OleGG不在O1中。在排序的随机访问数据结构中添加一个条目是很困难的,因此不会是线性的,总的复杂性将是*lognadd或insert。。。你怎么计算最小值?更新你的页面。我澄清了添加不是+而是添加到结果集,以及您是如何将新项插入O1中排序列表中查找项的排序列表中的?@OleGG不在O1中。在排序的随机访问数据结构中添加一个条目是很困难的,因此不会是线性的,总的复杂性将是*logn您的第二步将导致指针出现问题,因为优先级的变化,它们将被洗牌。。。或者你可以在给定的测试用例指针上运行你的算法,而不是索引。编写队列时,不要移动对象,而是移动它们的引用。第二步将导致指针出现问题,因为优先级发生变化,它们将被洗牌。。。或者你可以在给定的测试用例指针上运行你的算法,而不是索引。编写队列时,不要移动对象,而是移动它们的引用。