概念

栈是一种遵从 后进先出 原则的有序集合。
添加新元素的一端称为栈顶,另一端为栈底。
操作栈的元素时,只能从栈顶操作(添加、移除、取值)

栈的实现

我们需要实现以下功能:

  • push() 入栈的方法
  • pop() 出栈的方法
  • top() 获取栈顶元素的方法
  • size() 获取栈中元素个数的方法
  • clear() 清空栈的方法

基于 JavaScript 内置对象的方法实现一个数据结构,会对性能有所损耗,所以实现时优先选择传统 JavaScript 对象进行功能的实现。

  1. class Stack {
  2. constructor() {
  3. // 存储栈中数据
  4. this.data = [];
  5. // 记录栈中数据个数(相当于数组的 length )
  6. this.count = 0;
  7. }
  8. // push() 入栈方法
  9. push(item) {
  10. // 方法1:数组方法 push 添加
  11. // this.data.push(item);
  12. // 方法2:利用数组长度
  13. // this.data[this.data.length] = item;
  14. // 方法3:计数方式
  15. this.data[this.count] = item;
  16. this.count++; // 入栈后,count 自增
  17. }
  18. // pop() 出栈方法
  19. pop() {
  20. // 出栈前提是栈中存在元素
  21. if (this.isEmpty()) {
  22. console.log('栈为空!移除失败');
  23. return;
  24. }
  25. // 移除栈顶数据
  26. // 方法1:数组方法 pop移除
  27. // return this.data.pop();
  28. // 方法2:计数方式
  29. const temp = this.data[this.count - 1];
  30. delete this.data[this.count - 1];
  31. this.count--;
  32. return temp;
  33. }
  34. // isEmpty() 检测栈是否为空
  35. isEmpty() {
  36. return this.count === 0;
  37. }
  38. // top() 获取栈顶的元素
  39. top() {
  40. if (this.isEmpty()) {
  41. console.log('栈为空!获取失败');
  42. return;
  43. }
  44. return this.data[this.count - 1];
  45. }
  46. // size() 获取栈中元素个数
  47. size() {
  48. return this.count;
  49. }
  50. // clear() 清空栈
  51. clear() {
  52. this.data = [];
  53. this.count = 0;
  54. }
  55. }

力扣精选题

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

LeetCode 剑指 Offer 30. 包含min函数的栈(简单)

image.png

方法一:

在存储数据的栈外,再创建一个辅助栈,用于存储栈的最小值 stack = [-2, 0, -3] minStack = [-2, -2, -3]

  1. class MinStack {
  2. constructor() {
  3. // stackA 用于存储数据
  4. this.stackA = [];
  5. this.countA = 0;
  6. // stackB 为辅助栈 用于存储栈道最小值(数据降序排序)
  7. this.stackB = [];
  8. this.countB = 0;
  9. }
  10. push(item) {
  11. // stackA 正常入栈
  12. this.stackA[this.countA] = item;
  13. this.countA++;
  14. // stackB 如果没有数据,直接入栈
  15. // 如果当前元素小于等于 stackB栈顶元素,入栈
  16. if (this.countB === 0 || item <= this.min()) {
  17. this.stackB[this.countB] = item;
  18. } else {
  19. // 否则 入栈元素为 当前栈中最小值
  20. this.stackB[this.countB] = this.min();
  21. }
  22. this.countB++;
  23. }
  24. // 最小值函数 返回栈中最小值 即时辅助栈栈顶元素
  25. min() {
  26. return this.stackB[this.countB - 1];
  27. }
  28. // 获取栈顶元素
  29. top() {
  30. return this.stackA[this.countA - 1];
  31. }
  32. // 出栈
  33. pop() {
  34. delete this.stackA[this.countA - 1];
  35. this.countA--;
  36. delete this.stackB[this.countB - 1];
  37. this.countB--;
  38. }
  39. }
  40. // 时间复杂度:O(1),push(), pop(), top(), min() 四个函数的时间复杂度均为常数级别。
  41. // 空间复杂度:O(N),当共有 N 个待入栈元素时,辅助栈B 需要存储 N 个元素,使用O(N)额外空间。

方法二:

stack = [-2, 0, -3, 2 , -6] minStack = [-2, -3, -6] push():stack 正常入栈,minStack遇到小于等于 min() 元素时入栈 pop():先 检测辅助栈 top() === min() stack ,minStack出栈 再 stackA 正常出栈。

方法三:API大法

  1. class MinStack {
  2. constructor() {
  3. this.stack = [];
  4. }
  5. push(item) {
  6. this.stack.push(item);
  7. }
  8. top() {
  9. return this.stack[this.stack.length - 1];
  10. }
  11. min() {
  12. // return Math.min(...this.stack);
  13. return Math.min.apply(null, this.stack);
  14. }
  15. pop() {
  16. this.stack.pop();
  17. }
  18. }