[数据结构与算法] LeetCode-716 Max Stack

题目

Design a max stack that supports push, pop, top, peekMax and popMax.

  1. push(x) – Push element x onto stack.
  2. pop() – Remove the element on top of the stack and return it.
  3. top() – Get the element on the top.
  4. peekMax() – Retrieve the maximum element in the stack.
  5. popMax() – Retrieve the maximum element in the stack, and remove it. If you find more than one maximum elements, only remove the top-most one.

分析

类似于155. Min Stack,但是多了popMax()操作,这是本题的难点。popMax()操作需要弹出最大栈中最大的值,并且保持最大栈中元素的大小关系。关键在于:如何维护一个辅助最大栈,记录每次变更后的最大值。思考问题:

  1. 对于push()操作,如何维护辅助最大栈?
  2. 对于popMax()操作,最大值可能在最大栈的最底层,此时如何弹出?弹出后如何维护最大栈与辅助最大栈?
    对于第1点,操作和[155. Min Stack]完全相同。
    对于第2点,需要再开一个临时栈,临时存放被弹出最大值上面的若干元素。

代码如下:

//
// Created by simida on 2020/07/12.
//

// 加锁题,未经OJ测试

// time complexity
// space complexity O(n)


#include <stdio.h>
#include <iostream>
#include <stack>
using namespace std;

class MaxStack {
 private:
    stack<int> stack_; // 最大值栈
    stack<int> help_stack_; // 辅助最大值栈

 public:
    /** initialize your data structure here. */
    MaxStack() {
    }

	// O(1)
    void push(int x) {
      stack_.push(x);

      if (help_stack_.empty()) {
        help_stack_.push(x);

      } else if (x > help_stack_.top()) {
        help_stack_.push(x);
      } else {
        int top = help_stack_.top();
        help_stack_.push(top);
      }
    }

	// O(1)
    void pop() {
      stack_.pop();
      help_stack_.pop();
    }
    
	// O(1)
    int top() {
      return stack_.top();
    }

	// O(1)
    int peekMax() {
      return help_stack_.top();
    }

 	// O(n)
    int popMax() {
      stack<int> s;	// 临时栈
      int top = help_stack_.top();

      // 将最大值上面的元素放入临时栈,然后弹出最大值即可
      while (stack_.top() != top) {
        s.push(stack_.top());
        stack_.pop();
      }
      stack_.pop(); // 将stack_最顶端的最大值弹出

      // 将辅助最大值栈help_stack_的最大值弹出
      while (!help_stack_.empty() && help_stack_.top() == top) { // //特别注意: 这里的empty判断不能丢掉,否则可能访问空栈的栈顶元素,程序报错。
        help_stack_.pop();
      }

      // 对于stack_: 将临时栈s中的元素重新放回stack_中
      // 对于help_stack_: 重新生成辅助最大值栈
      while (!s.empty()) {
        push(s.top());
        s.pop();
      }

      return top;
    }
};


int main() {
// Your MaxStack object will be instantiated and called as such:

  MaxStack* obj = new MaxStack();

  obj->push(5);
  printf("top is %d\n", obj->top()); // 5

  obj->push(4);
  printf("top is %d\n", obj->top()); // 4

  obj->push(3);
  printf("top is %d\n", obj->top()); // 3

  obj->push(2);
  printf("top is %d\n", obj->top()); // 2

  obj->push(1);
  printf("top is %d\n", obj->top()); // 1

  printf("\nstop push\n");
  obj->popMax();
  printf("top is %d\n", obj->top()); // 1
  printf("peekMax is %d\n", obj->peekMax()); // 4

  obj->popMax();
  printf("top is %d\n", obj->top()); // 1
  printf("peekMax is %d\n", obj->peekMax()); // 3

  obj->popMax();
  printf("top is %d\n", obj->top()); // 1
  printf("peekMax is %d\n", obj->peekMax()); // 2

  obj->pop();
  printf("top is %d\n", obj->top()); // 2
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值