剑指 Offer——Day1栈与队列(简单)

151 阅读2分钟

栈(Stack):

  • 后进先出特性(LIFO)
  • 压栈(Push):将元素放入栈顶
  • 弹栈(Pop):从栈顶取出元素
  • 查看栈顶(Peek):查看栈顶元素

队列(Queue):

  • 先进先出特性(FIFO)
  • 入队(Enqueue):将元素放入队尾
  • 出队(Dequeue):从队头取出元素
  • 查看队头(Peek):查看队头元素

剑指 Offer 09. 用两个栈实现队列

栈底元素(对应队列头)无法直接删除;

使用两个栈,设stackA = [1,2,3]和一个空栈stackB = [],循环遍历stackA将元素一次加入stackB,那么stackB = [3,2,1],栈B是A的倒序;

  • 使用stackA.push()实现队列的appendTail()功能;
  • 使用stackB.pop()实现队列的deleteHead()功能
var CQueue = function() {
   this.stackA = [];//用于入队的栈
   this.stackB = [];//用于出兑的栈
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
    this.stackA.push(value);
};

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function() {
    if (this.stackB.length === 0) {
        //如果stack2为空
        while (this.stackA.length !== 0) {
            this.stackB.push(this.stack1.pop())
        }
    }

    if (this.stackB.length === 0) {
        return -1;
    } else {
        return this.stackB.pop();
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * var obj = new CQueue()
 * obj.appendTail(value)
 * var param_2 = obj.deleteHead()
 */

剑指 Offer 30. 包含 min 函数的栈

普通栈的push()pop()都是O(1),min()因为需要遍历整个栈所以是O(N)的;

本题的重点是如果降低min()的复杂度为O(1),需要使用辅助栈:

  • 栈(stack):用于存储数据
  • 辅助栈(minStack):minStack存储stack中所有非严格降序元素的子序列,则stack的最小元素始终在minStack中,min()只需要minStack.pop()即可。
/**
 * initialize your data structure here.
 */
var MinStack = function() {
    this.stack = [];
    this.minStack = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    this.stack.push(x);
    if (this.minStack.length === 0 || x <= this.minStack[this.minStack.length - 1]) {
        this.minStack.push(x);
    }
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    const popped = this.stack.pop();
    if (this.minStack[this.minStack.length - 1] == popped) {
        this.minStack.pop();
    }
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.stack[this.stack.length - 1];
};

/**
 * @return {number}
 */
MinStack.prototype.min = function() {
    return this.minStack[this.minStack.length - 1];
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(x)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.min()
 */

什么是非严格降序?

非严格降序元素是指在一个序列中,元素的排列顺序不是严格按照降序排列的,但是元素之间的相对大小关系仍然满足降序。换句话说,非严格降序元素是指在一个序列中,元素的排列可能存在相同值的情况,但整体上仍然保持降序的特征。

举个例子来说明,假设有一个序列 [9, 7, 7, 5, 3, 1],其中元素 7 出现了两次。尽管 7 出现两次,这个序列仍然可以被认为是非严格降序的,因为整体上元素的排列是按降序排列的。

非严格降序元素在某些排序算法和数据处理任务中可能具有一定的影响,因为相同值的元素可能会引起一些特殊情况或操作的注意。在处理这些元素时,需要考虑到它们的相对顺序,以确保正确的处理和结果。