场景:
实现一个栈,带有出栈(pop),入栈(push),取最小元素(getMin)三个方法。要保证这三个方法的时间复杂度都是O(1)。
方法一:
- 设两个栈A/B,A:存放原始数据,B:栈顶为最小元素,其余为最小元素的备胎;
- 入栈:
(1) 当第一个元素进入栈A时,索引“0”进入栈B。索引“0”所指即为栈A的当前最小值;
(2) 每当新元素进入栈A时,将新元素与B的栈顶元素(即栈A当前最小值)对比。若新元素小于B的栈顶元素,则新元素的下标进入栈B; - 出栈
当A有出栈时,若A栈顶元素的索引为B的栈顶元素(即,出栈元素为A的最小值),则B的栈顶元素出栈。出栈后,B的栈顶元素指向A原本第二小元素,即A当前最小元素。 取最小元素。
B的栈顶所指向的即为栈A的最小元素。
方法二:
使用带有尾指针的单链表。
链表结点结构
class Node { int value; int min; Node *next; public Node(int value, int min) { this.value = value; this.min = min; } }
栈操作
class MinStack { Node *top; public MinStack(){ } // 入栈 public void push(int value) { if (top == null) { top = new Node(value, value); } else { Node* e = new Node(value, Math.min(value, top.min)); e->next = top; top = e; } } // 出栈 int pop() { if (top == null) { throw new Exception("Stack is empty"); } int result = top->value; Node* temp = top; top = top->next ; free(temp ); return result; } public int getMin() { return top->min; } }