最小栈的实现(附代码)

176 阅读3分钟

实现一个栈,带有出栈(pop),入栈(push),取最小元素(getMin)三个方法。要保证这三个方法的时间复杂度都是O(1)

实现一个带有出栈(pop),入栈(push)和取最小元素(getMin)三个方法的栈,并且要保证这三个方法的时间复杂度都是 O(1),可以采用以下策略:

  1. 使用两个栈,一个主栈用于存储元素,另一个辅助栈用于存储当前的最小元素。

  2. 当执行 push 操作时,将元素压入主栈。同时,比较要压入的元素与辅助栈顶元素的大小,如果辅助栈为空或者要压入的元素小于等于辅助栈顶元素,则将要压入的元素也压入辅助栈。

  3. 当执行 pop 操作时,从主栈弹出栈顶元素。同时,比较弹出的元素与辅助栈顶元素的大小,如果它们相等,则也从辅助栈中弹出栈顶元素。

  4. 当执行 getMin 操作时,直接返回辅助栈的栈顶元素,该元素即为当前的最小元素。

下面是使用 Swift 语言实现的示例代码:

struct MinStack {
    private var stack: [Int] = []
    private var minStack: [Int] = []

    mutating func push(_ value: Int) {
        stack.append(value)
        if minStack.isEmpty || value <= minStack.last! {
            minStack.append(value)
        }
    }

    mutating func pop() {
        if stack.isEmpty {
            return
        }

        let poppedValue = stack.removeLast()
        if poppedValue == minStack.last! {
            minStack.removeLast()
        }
    }

    func getMin() -> Int? {
        return minStack.last
    }
}

使用示例:

var stack = MinStack()
stack.push(3)
stack.push(5)
stack.push(2)
stack.push(1)

print(stack.getMin()) // 输出: 1

stack.pop()
stack.pop()

print(stack.getMin()) // 输出: 3

这样,就可以在 O(1) 的时间复杂度内实现出栈、入栈和取最小元素的操作。

实现一个队列,带有出队(deQueue),入队(enQueue),取最小元素(getMin)三个方法。要保证这三个方法的时间复杂度都尽可能小

要实现一个带有出队(deQueue),入队(enQueue)和取最小元素(getMin)三个方法的队列,并且要保证这三个方法的时间复杂度尽可能小,可以采用以下策略:

  1. 使用两个辅助队列,一个主队列用于存储元素,另一个辅助队列用于存储当前的最小元素。

  2. 当执行 enQueue 操作时,将元素加入主队列。同时,比较要加入的元素与辅助队列中的最小元素的大小,如果辅助队列为空或者要加入的元素小于等于辅助队列中的最小元素,则将要加入的元素也加入辅助队列。

  3. 当执行 deQueue 操作时,从主队列中移除队首元素。同时,比较移除的元素与辅助队列中的最小元素的大小,如果它们相等,则也从辅助队列中移除队首元素。

  4. 当执行 getMin 操作时,直接返回辅助队列中的最小元素,该元素即为当前的最小元素。

下面是使用 Swift 语言实现的示例代码:

struct MinQueue {
    private var queue: [Int] = []
    private var minQueue: [Int] = []

    mutating func enQueue(_ value: Int) {
        queue.append(value)
        while !minQueue.isEmpty && value <= minQueue.last! {
            minQueue.removeLast()
        }
        minQueue.append(value)
    }

    mutating func deQueue() {
        if queue.isEmpty {
            return
        }

        let dequeuedValue = queue.removeFirst()
        if dequeuedValue == minQueue.first! {
            minQueue.removeFirst()
        }
    }

    func getMin() -> Int? {
        return minQueue.first
    }
}

使用示例:

var queue = MinQueue()
queue.enQueue(3)
queue.enQueue(5)
queue.enQueue(2)
queue.enQueue(1)

print(queue.getMin()) // 输出: 1

queue.deQueue()
queue.deQueue()

print(queue.getMin()) // 输出: 2

这样,我们就可以尽可能保证出队、入队和取最小元素这三个方法的时间复杂度尽可能小。