实现一个栈,该栈带有出栈(pop)、入栈(push)、取最小元素(getMin)3 个方法。要保证这 3 个方法的时间复杂度都是 O(1)。
详细的解法步骤如下。
**
设原有的栈叫作栈 A,此时创建一个额外的「备胎」栈 B,用于辅助栈 A。
当第 1 个元素进入栈 A 时,让新元素也进入栈 B。这个唯一的元素是栈 A 的当前最小值。
之后,每当新元素进入栈 A 时,比较新元素和栈 A 当前最小值的大小,如果小于栈 A 当前最小值,则让新元素进入栈 B,此时栈 B 的栈顶元素就是栈 A 当前最小值。
每当栈 A 有元素出栈时,如果出栈元素是栈 A 当前最小值,则让栈 B 的栈顶元素也出栈。此时栈 B 余下的栈顶元素所指向的,是栈 A 当中原本第 2 小的元素,代替刚才的出栈元素成为栈 A 的当前最小值。(备胎转正。)
当调用 getMin 方法时,返回栈 B 的栈顶所存储的值,这也是栈 A 的最小值。
显然,这个解法中进栈、出栈、取最小值的时间复杂度都是 O(1),最坏情况空间复杂度是 O(n)。
/*** initialize your data structure here.*/var MinStack = function() {this.mainStack = []this.minStack = []};/*** 入栈操作* @param element 入栈的元素*/MinStack.prototype.push = function(element) {this.mainStack.push(element)//如果辅助栈为空,或者新元素小于或等于主站最小值(辅助栈栈顶),则将新元素压入辅助栈if (this.minStack.empty() || element <= minStack.peek()) {this.minStack.push(element);}}/*** 出栈操作*/MinStack.prototype.pop = function(element) {//如果出栈元素和辅助栈栈顶元素值相等,辅助栈出栈if (mainStack.peek().equals(minStack.peek())) {minStack.pop();}return mainStack.pop();}/*** 获取栈的最小元素*/MinStack.prototype.getMin = function() {if (mainStack.empty()) {throw new Exception("stack is empty");}return minStack.peek();}
