image.png

基本数据结构

队列

image.png
特点: 先进先出
image.png

  1. class Queue {
  2. constructor() {
  3. this.dataSource = [];
  4. }
  5. enqueue(ele) {
  6. this.dataSource.push(ele);
  7. }
  8. dequeue() {
  9. return this.dataSource.shift();
  10. }
  11. back() {
  12. return this.dataSource[this.dataSource.length - 1];
  13. }
  14. font() {
  15. return this.dataSource[0];
  16. }
  17. isEmpty() {
  18. return this.dataSource.length === 0;
  19. }
  20. toString() {
  21. return this.dataSource.toString();
  22. }
  23. }
  24. const queue = new Queue();
  25. queue.enqueue('guan');
  26. queue.enqueue('qing');
  27. queue.enqueue('chao');
  28. console.log(queue.toString());
  29. console.log(queue.dequeue());

image.png
特点:先进后出
image.png

  1. class Stack {
  2. constructor() {
  3. this.dataSource = [];
  4. }
  5. push(ele) {
  6. this.dataSource.push(ele);
  7. }
  8. pop() {
  9. return this.dataSource.pop();
  10. }
  11. //获取栈顶元素
  12. peek() {
  13. return this.dataSource[this.dataSource.length - 1];
  14. }
  15. clear() {
  16. this.dataSource.length = 0;
  17. }
  18. length() {
  19. return this.dataSource.length;
  20. }
  21. toString() {
  22. return this.dataSource.toString();
  23. }
  24. isEmpty(){
  25. return this.dataSource.length===0;
  26. }
  27. }
  28. const stack = new Stack();
  29. stack.push('guan');
  30. stack.push('qing');
  31. stack.push('chao');
  32. console.log(stack.toString());
  33. console.log(stack.pop());
  34. console.log(stack.peek());

练习题目

循环队列

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。
  1. MyCircularQueue circularQueue = new MycircularQueue(3); // 设置长度为 3
  2. circularQueue.enQueue(1); // 返回 true
  3. circularQueue.enQueue(2); // 返回 true
  4. circularQueue.enQueue(3); // 返回 true
  5. circularQueue.enQueue(4); // 返回 false,队列已满
  6. circularQueue.Rear(); // 返回 3
  7. circularQueue.isFull(); // 返回 true
  8. circularQueue.deQueue(); // 返回 true
  9. circularQueue.enQueue(4); // 返回 true
  10. circularQueue.Rear(); // 返回 4

有效的括号

给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

  1. //case: ()[]{}
  2. // 思路: 遇到左括号push相应的右括号,右括号,判断栈顶元素是否跟当前右括号相等
  3. var isValid = function(s) {
  4. var stack = new Stack();
  5. for(var i = 0; i<s.length; i++){
  6. //碰到左括号,push右括号
  7. if(s[i] === "(") {
  8. stack.push(")");
  9. } else if(s[i] === "[") {
  10. stack.push("]");
  11. } else if(s[i] === "{") {
  12. stack.push("}");
  13. } else{
  14. //不是左括号,判断栈是否为空或栈顶元素是否等当前元素
  15. if(!stack.isEmpty || stack.peek() != s[i]){
  16. return false
  17. }else{
  18. stack.pop()
  19. }
  20. }
  21. }
  22. return !stack.top;
  23. };

最小栈

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

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

示例:

  1. 输入:
  2. ["MinStack","push","push","push","getMin","pop","top","getMin"]
  3. [[],[-2],[0],[-3],[],[],[],[]]
  4. 输出:
  5. [null,null,null,null,-3,null,0,-2]
  6. 解释:
  7. MinStack minStack = new MinStack();
  8. minStack.push(-2);
  9. minStack.push(0);
  10. minStack.push(-3);
  11. minStack.getMin(); --> 返回 -3.
  12. minStack.pop();
  13. minStack.top(); --> 返回 0.
  14. minStack.getMin(); --> 返回 -2.

思路:定义两个栈 smain, smin, smin栈顶始终是最小元素, 同时进行push pop 操作
image.png

  1. var MinStack = function() {
  2. this.smain = [];
  3. this.smin = [];
  4. };
  5. /**
  6. * @param {number} x
  7. * @return {void}
  8. */
  9. MinStack.prototype.push = function(x) {
  10. var smain = this.smain;
  11. var smin = this.smin;
  12. smain.push(x);
  13. if (smin.length === 0) {
  14. smin.push(x);
  15. } else if (x < smin[smin.length-1]) {
  16. smin.push(x);
  17. }
  18. else {
  19. smin.push(smin[smin.length-1]);
  20. }
  21. };
  22. /**
  23. * @return {void}
  24. */
  25. MinStack.prototype.pop = function() {
  26. var smain = this.smain;
  27. var smin = this.smin;
  28. smain.pop();
  29. smin.pop();
  30. };
  31. /**
  32. * @return {number}
  33. */
  34. MinStack.prototype.top = function() {
  35. var smain = this.smain;
  36. // var smin = this.smin;
  37. return smain[smain.length-1];
  38. };
  39. /**
  40. * @return {number}
  41. */
  42. MinStack.prototype.getMin = function() {
  43. // var smain = this.smain;
  44. var smin = this.smin;
  45. return smin[smin.length-1];
  46. };

232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明: 你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

思路: 用两个栈来实现队列
image.png
image.png
image.png

  1. // 使用两个数组的栈方法(push, pop) 实现队列
  2. /**
  3. * Initialize your data structure here.
  4. */
  5. var MyQueue = function() {
  6. this.stack1 = [];
  7. this.stack2 = [];
  8. };
  9. /**
  10. * Push element x to the back of queue.
  11. * @param {number} x
  12. * @return {void}
  13. */
  14. MyQueue.prototype.push = function(x) {
  15. this.stack1.push(x);
  16. };
  17. /**
  18. * Removes the element from in front of queue and returns that element.
  19. * @return {number}
  20. */
  21. MyQueue.prototype.pop = function() {
  22. const size = this.stack2.length;
  23. if(size) {
  24. return this.stack2.pop();
  25. }
  26. while(this.stack1.length) {
  27. this.stack2.push(this.stack1.pop());
  28. }
  29. return this.stack2.pop();
  30. };
  31. /**
  32. * Get the front element.
  33. * @return {number}
  34. */
  35. MyQueue.prototype.peek = function() {
  36. const x = this.pop();
  37. this.stack2.push(x);
  38. return x;
  39. };
  40. /**
  41. * Returns whether the queue is empty.
  42. * @return {boolean}
  43. */
  44. MyQueue.prototype.empty = function() {
  45. return !this.stack1.length && !this.stack2.length
  46. };

https://labuladong.github.io/algo/2/20/51/

var MyStack = function() {
    this.stack = []
}

/**
 * Push element x onto stack. 
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function(x) {
    return this.stack[this.stack.length] = x
}

/**
 * Removes the element on top of the stack and returns that element.
 * @return {number}
 */
MyStack.prototype.pop = function() {
    const remove = this.stack[this.stack.length - 1]
    this.stack.length -= 1
    return remove
}

/**
 * Get the top element.
 * @return {number}
 */
MyStack.prototype.top = function() {
    return this.stack[this.stack.length - 1]
}

/**
 * Returns whether the stack is empty.
 * @return {boolean}
 */
MyStack.prototype.empty = function() {
    if (this.stack.length === 0) {
        return true
    } else {
        return false
    }
}

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