【leetcode】155. 最小栈

标题设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

  1. 实现 MinStack 类:
  2. MinStack() 初始化堆栈对象。
  3. void push(int val) 将元素val推入堆栈。
  4. void pop() 删除堆栈顶部的元素。
  5. int top() 获取堆栈顶部的元素。
  6. int getMin() 获取堆栈中的最小元素。

初版

// 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

// 实现 MinStack 类:

// MinStack() 初始化堆栈对象。
// void push(int val) 将元素val推入堆栈。
// void pop() 删除堆栈顶部的元素。
// int top() 获取堆栈顶部的元素。
// int getMin() 获取堆栈中的最小元素。


class MinStack {
  constructor() {
    this.stackA = [];
    this.countA = 0;
    
  }

  // input stack
  push(item) {
    this.stackA[this.countA] = item;
    this.countA++;
  }

  // output stack
  pop() {
    if (this.isEmpty()) {
      return;
    }

    const value = this.top();
    this.countA--;
    return value;
  }

  top() {
    return this.stackA[this.countA - 1];
  }

  isEmpty() {
    return this.countA === 0;
  }

  // min
  getMin() {
    console.log(this.stackA)
    return Math.min(...this.stackA.slice(0, this.countA));
  }
}

const minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
const top1 = minStack.getMin(); // --> 返回 -3.
console.log("top1: ", top1);
minStack.pop();
const top2 = minStack.top(); // --> 返回 0.
console.log("top2: ", top2);
const top3 = minStack.getMin(); // --> 返回 -2.
console.log("top3: ", top3);

LeetCode的执行时间比较高 500ms,感觉是下面的代码用时多

getMin() {
    console.log(this.stackA)
    return Math.min(...this.stackA.slice(0, this.countA));
  }

第二版 优化了一点点:

class MinStack {
  constructor() {
    this.stackA = [];
    this.countA = 0;
    
  }

  // input stack
  push(item) {
    this.stackA[this.countA] = item;
    this.countA++;
  }

  // output stack
  pop() {
    if (this.isEmpty()) {
      return;
    }

    const value = this.top();
    this.stackA.length--;
    this.countA--;
    return value;
  }

  top() {
    return this.stackA[this.countA - 1];
  }

  isEmpty() {
    return this.countA === 0;
  }

  // min
  getMin() {
    return Math.min.apply(null, this.stackA);
  }
}

const minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
const top1 = minStack.getMin(); // --> 返回 -3.
console.log("top1: ", top1);
minStack.pop();
const top2 = minStack.top(); // --> 返回 0.
console.log("top2: ", top2);
const top3 = minStack.getMin(); // --> 返回 -2.
console.log("top3: ", top3);

LeetCode的执行时间还是比较高 200ms

第三版

上面的代码几乎没有用原生的方法,于是想着用js原生方法,看一看能不能有改善

class MinStack {
  constructor() {
    this.stackA = [];
  }

  // input stack
  push(item) {
    this.stackA[this.stackA.length] = item;
  }

  // output stack
  pop() {
    if (this.isEmpty()) {
      return;
    }
    return this.stackA.pop();
  }

  top() {
    return this.stackA[this.stackA.length - 1];
  }

  isEmpty() {
    return this.stackA.length === 0;
  }

  // min
  getMin() {
    return Math.min.apply(null,this.stackA);
  }
}


还是200ms,这种思路就不行,数组中取最小值,太浪费时间,想到了取巧的方式,就是之前写过的[双数组的方法](https://blog.csdn.net/Martin164/article/details/124680655)

想了一会又想到一种办法(冥思苦想)

思考过程:
最短时间获取到最小值,就需要把最小值存起来,一种就是上面的双数组方法,把最小值放入另一个数组中,同理,可以把最小值放入每个类似链表的节点上,这里就是一个对象,每次添加值的时候,添加一个对象,这个对象包含当前值和最小值

class MinStack {
  constructor() {
    this.stackA = [];
  }

  // input stack
  push(item) {
    if (this.isEmpty()) {
      this.stackA[this.stackA.length] = {
        value: item,
        min: item
      }
    }else {
      if (item > this.stackA[this.stackA.length - 1].min) {
        this.stackA[this.stackA.length] = {
          value: item,
          min: this.stackA[this.stackA.length - 1].min,
        };
      } else {
        this.stackA[this.stackA.length] = {
          value: item,
          min: item,
        };
      }
    }
  }

  // output stack
  pop() {
    if (this.isEmpty()) {
      return;
    }
    return this.stackA.pop().value;
  }

  top() {
    return this.stackA[this.stackA.length - 1].value;
  }

  isEmpty() {
    return this.stackA.length === 0;
  }

  // min
  getMin() {
    return this.stackA[this.stackA.length - 1].min;
  }
}

最终版:

上面的代码写的繁琐了 提交leetcode 100ms,主要是按照下意识的思路写的,也比较方便理解过程,优化一下:

class MinStack {
  constructor() {
    this.stackA = [];
  }

  // input stack
  push(item) {
    // 获取当前的最小值
    const minValue =
      (this.isEmpty() || item <= this.stackA[this.stackA.length - 1].min)
        ? item
        : this.stackA[this.stackA.length - 1].min;
     
    this.stackA[this.stackA.length] = {
      value: item,
      min: minValue,
    };
  }

  // output stack
  pop() {
    if (this.isEmpty()) {
      return;
    }
    return this.stackA.pop().value;
  }

  top() {
    return this.stackA[this.stackA.length - 1].value;
  }

  isEmpty() {
    return this.stackA.length === 0;
  }

  // min
  getMin() {
    return this.stackA[this.stackA.length - 1].min;
  }
}

执行时间84ms,比较满意,抽空去LeetCode看看大神的方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值