美文网首页
数据结构:min stack & max queue

数据结构:min stack & max queue

作者: akak18183 | 来源:发表于2017-06-27 05:42 被阅读0次

栈和队列都是常用的数据结构,有时候需要大量进行输出栈/队列里的最大/小值,假如每次都调用min/max函数,效率是O(n),这对于大量操作而言,是不够满意的。因此,可以设计支持平均O(1)时间复杂度返回大小值的min stack和max queue。至于最小最大,原理都是一样的,稍微改一下就可以变成另外一种。

  1. min stack
class MinStack:
    def __init__(self):
        self.min = None
        self.stack = []
        
    # @param x, aninteger
    # @return an integer
    def push(self, x):
        if not self.stack:
            self.stack.append(0)
            self.min = x
        else:
            self.stack.append(x - self.min)
            if x < self.min:
                self.min = x

    # @return nothing
    def pop(self):
        x = self.stack.pop()
        if self.stack:
            if x < 0:
                self.min = self.min - x
        else:
            x = self.min
            self.min = None
        print(x)

    # @return aninteger
    def top(self):
        x = self.stack[-1]
        if x > 0:
            return x + self.min
        else:
            return self.min
        
    # @return aninteger
    def getMin(self):
        return self.min

这个实现很巧妙,只用一个数组就实现了最小栈。关键就是不直接放入数值n,而是放入n-min,这样假如n大于min,那么在数组里面体现就是正数,否则是负数,出栈的时候就可以根据情况更新。
假如出栈的时候是正数,说明其入栈的时候不是最小值,可以直接出;否则,说明其就是最小值,因为当时入栈的值其实是n-min_prev,而现在的min其实是n,因此min_prev = n - (n - min_prev)也就是现在的min去减pop出来的值,从而还原n入栈之前的最小值。
同样,top看的数,也是n-min_prev,只不过不用更新min值,假如大于0,说明min还是之前的,相加即可;否则,说明min更新为当前数,直接返回min。
不过有一点需要注意,就是栈为空的时候的处理。
这个做法效率非常高,空间和时间复杂度都是O(1)(因为本来就需要一个栈,不算额外空间复杂度)。

  1. max queue
from collections import deque
class maxQ:
    def __init__(self):
        self.D = deque()
        self.Max = deque()

    def push(self, n):
        self.D.append(n)
        while self.Max and self.Max[-1] < n:
            self.Max.pop()
        self.Max.append(n)

    def pop(self):
        if self.Max[0] == self.D[0]:
            self.Max.popleft()
        self.D.popleft()
    
    def getMax(self):
         return self.Max[0] 
队列的情况和栈完全不一样。可以使用两个双端队列,一个专门放max值,每次push进入一个数,就把其值放在max队列里面,并pop掉前面所有比它小的。这是因为,刚刚进来的这个数比之前所有数保留在队列里的时间都久,因此假如有一些值比它还小,因为那些数在它前面出去,所以不可能有机会成为队列的max。相等的值要留下来,这是为了pop。这样max queue的元素是按照降序排列的。
然后就是pop的时候更新max。假如pop出去的是max,那就把它也从max里面pop掉。因为保留了相等的,假如后面有一样的,也不至于全部都删掉。 
max queue的效率低一些,push操作平均是O(1),因为有时候需要连续pop。然后需要额外的O(n)空间。

有了这两个数据结构,max stack和min queue也是可以得到的,原理相同稍作修改,此处不再赘述。

相关文章

  • 数据结构:min stack & max queue

    栈和队列都是常用的数据结构,有时候需要大量进行输出栈/队列里的最大/小值,假如每次都调用min/max函数,效率是...

  • 单调队列

    单调队列,也可以叫做Monotonic Queue这种数据结构主要可以优化能够用max/min heap 解决的题...

  • Java算法和数据结构概述

    一、数据结构 1、常见数据结构:Array(数组)、Stack(栈)、Queue(队列)、LinkedList(链...

  • 基本数据结构-树

    基本数据结构 简介 基本数据结构有:array, list, queue, stack, map, tree, ...

  • 面试guidemap

    1. 数据结构 线性结构(array/linked list/stack/queue): array-based ...

  • 数据结构(一):数据结构和算法

    数据结构:计算机存储、组织数据的方式 常见的数据结构:数组(Array)、栈(Stack)、队列(Queue)、链...

  • 2020-05-17-Java数据结构-Stack和Queue

    Stack Queue 参考: java 中的Stack、Queue、Deque

  • alg4th-1.3

    algorithm 4th笔记(1.3) 封装数据结构 Bag,Stack,Queue 三种数据结构各有各的特点,...

  • Java数据类型

    Java数据结构中常用的数据结构包含如下8种: 1:数组(Array) 2:栈(Stack) 3:队列(Queue...

  • 数据结构 03 双向队列

    双向队列 它是一种混合线性数据结构, 涵盖Stack和Queue的全部能力.

网友评论

      本文标题:数据结构:min stack & max queue

      本文链接:https://www.haomeiwen.com/subject/jcyscxtx.html