Renyddd Site
Created: 13 Jan 2023

Coding Interviews 30 可 O(1) 查找最小值的栈

题目

  • 题目链接
  • 题目概述:自定义一个栈结构,添加可找到最小值的方法 min(),并要求其 min(),push(),pop() 方法都得在 O(1) 完成

思考点

  1. O(1) 时间复杂度 这就要求了你不可能在每次 push 新元素的时候,通过排序去维护一个有序数组。 且 min 方法也不能动态地找出当前最小值。
  2. 存储结构 两种常见的方式,存数据还是存索引?这里也许不是很必要。 在看了官方题解后,我才意识到还需要考虑存储数据类型。
  3. 存储数据类型 有序列表还是最小值本身? 其实自己思路的一开始都是以有序列表为基础的,但随后才发现有序列表的维护很难在 O(1) 完成。且题解给到的对最小值本身的栈存储,才让自己清醒,你需要的仅仅是对当前集合状态最小值的保存。

题解

最小值栈记录当前状态

instance variable 中的 datastack 存储栈本身的数据,由 minstack 存储当前状态下的最小值信息。

补充解释当前状态等于当前栈大小。并且弹出 minstack 不影响其底下元素有效性。

import sys


class MinStack:

    def __init__(self):
        self.data_stack = []
        self.min_stack = []
        self.min_stack.append(sys.maxsize)

    def push(self, x: int) -> None:
        self.data_stack.append(x)
        cur_min = self.min_stack[len(self.min_stack)-1]
        if x < cur_min:
            self.min_stack.append(x)
        else:
            self.min_stack.append(cur_min)

    def pop(self) -> None:
        self.data_stack.pop()
        if len(self.min_stack) > 1: # 避免弹出 sys.maxsize
            self.min_stack.pop()

    def top(self) -> int:
        return self.data_stack[len(self.data_stack)-1]

    def min(self) -> int:
        return self.min_stack[len(self.min_stack)-1]

头插链表并存储当前状态最小值

思路来自评论区 Top1。

Node 节点分别存储新加节点值以及当前状态下的最小值,并且由头插法实现 push 方法。

class Node:

    def __init__(self, data: int, min: int, next):
        self.data = data
        self.cur_min = min
        self.next = next


class MinStackLinked:

    def __init__(self):
        self.head = None

    def push(self, x: int) -> None:
        if self.head is None:
            self.head = Node(x, x, None)
        else:
            # 头插
            self.head = Node(x, min(self.head.cur_min, x), self.head)

    def pop(self) -> None:
        self.head = self.head.next

    def top(self) -> int:
        return self.head.data

    def min(self) -> int:
        return self.head.cur_min

PriorityQueue

思路来自评论区 Top2。

该方法不符合题目要求,因其只有插入效率为 O(1),而弹出效率为 O(n)。但这种有趣的思路值得借鉴。

优先队列定义:

  1. 每个元素都有自己的优先级;
  2. 优先级最高的元素先得到服务;
  3. 同等优先级的元素按照其插入顺序得到服务;

备注一个从 geeksforgeeks 摘抄的比喻:

For example, In airlines, baggage with the title “Business” or “First-class” arrives earlier than the rest.

Creative Commons License
renyddd by Renyddd is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.