Algorithm 获取“的编号”;“朋友”;塔

Algorithm 获取“的编号”;“朋友”;塔,algorithm,data-structures,Algorithm,Data Structures,给定编号为1、2、3、…、n的塔及其高度(h[i]=塔[i]的高度)和数字k 两座a、b塔被视为朋友: a-b=k h[a]==h[b] max(h[a+1],h[a+2]…h[b-1])您可以使用deque提供O(n)算法。 每一步: Remove too old elements from the deque head (if currentindex - index >= k) Remove elements from tail that have no ch

给定编号为1、2、3、…、n的塔及其高度(
h[i]=塔[i]
的高度)和数字k

两座a、b塔被视为朋友:

  • a-b=k
  • h[a]==h[b]

  • max(h[a+1],h[a+2]…h[b-1])您可以使用deque提供O(n)算法。
    每一步:

    Remove too old elements from the deque head  
           (if currentindex - index >= k)  
    Remove elements from tail that have no chance to become maximum 
           in the k-size window (those < currentvalue)  
    Add new element (index) to the deque tail  
    
    从deque头部移除太旧的元素
    (如果当前索引-索引>=k)
    从尾部移除没有机会达到最大值的元素
    在k大小窗口中(那些<当前值)
    将新元素(索引)添加到deque尾部
    
    这会将max元素的索引保留在deque顶部的k-size窗口中,因此您可以确定-两个塔之间是否存在较大的值

    使用伪码描述(滑动最小值)算法:

    详细说明我的评论,您可以使用答案构建一个队列,该队列可以跟踪两座塔楼之间的最大元素。移动到下一个元素只需要
    O(1)
    摊销时间。我用伪代码做了一个简单的实现,假设该语言支持一个标准堆栈(如果它不支持的话,我会感到惊讶)。有关说明,请参阅

    您的算法现在非常简单。将第一个
    k
    元素放入队列。然后,重复检查距离
    k
    处的两个塔是否具有相同的高度,检查中间的最大值(即队列的最大值)是否最大,然后移动到下一个两个塔。更新队列需要
    O(1)
    摊销时间,因此此算法在
    O(n)
    中运行,这显然是最优的

    MaxQueue queue
    for (int i = 1; i <= k; i++)    // add first k towers to queue
        queue.enqueue(h[i])
    for (int i = k+1; i <= n; i++)
        if h[i] == h[i-k] and h[i] >= queue.getMax()
            ans++
        queue.enqueue(h[i])
        queue.dequeue()
    
    MaxQueue队列
    
    对于(int i=1;i),您可以使用答案有效地获得滑动最大值(问题是关于最小值,但这种变化很简单)。然后您可以在
    O(n)
    时间内解决此问题。“对于较大的n,程序将消耗RAM”:你能解释一下吗?这个算法不使用额外的存储空间!使用deque也不会减少存储空间!因为n比k大,所以如果我使用数组,我必须存储所有的数字到数组->wastedI解决了它!感谢链接@HeusterDon't know which down vote。这是正确的答案(虽然它可以更明确一点如何工作)。这个问题不需要Deque。检查我的解决方案。嗨。你能编辑这个答案吗?我想删除我的否决票。
    class TupleStack
        Stack stack
    
        void push(int x)
            if stack.isEmpty()
                stack.push((value: x, max: x))
            else 
                stack.push((value: x, max: max(x, stack.peek().max))
    
        int pop()
            return stack.pop().value
    
        bool isEmpty()
            return stack.isEmpty()
    
        int getMax()
            if isEmpty()
                return -infinity
            else
                return stack.peek().max
    
    class MaxQueue
        TupleStack stack1
        TupleStack stack2
    
        void enqueue(int x)
            stack1.push(x)
    
        int dequeue()
            if stack2.isEmpty()
                while !stack1.isEmpty()
                    stack2.push(stack1.pop())
            return stack2.pop()
    
        int getMax()
            return max(stack1.getMax(), stack2.getMax())
    
    MaxQueue queue
    for (int i = 1; i <= k; i++)    // add first k towers to queue
        queue.enqueue(h[i])
    for (int i = k+1; i <= n; i++)
        if h[i] == h[i-k] and h[i] >= queue.getMax()
            ans++
        queue.enqueue(h[i])
        queue.dequeue()