Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

JavaScript 数据结构:栈和队列 #32

Open
fantasticit opened this issue Aug 2, 2019 · 0 comments
Open

JavaScript 数据结构:栈和队列 #32

fantasticit opened this issue Aug 2, 2019 · 0 comments

Comments

@fantasticit
Copy link
Owner

栈遵循 后进先出 的原则。

/**
 * 栈
 * 后进先出
 */
class Stack {
  constructor() {
    this.items = [];
  }

  // 添加元素
  push(value) {
    this.items.push(value);
  }

  // 返回栈顶的元素
  peek() {
    return this.items[this.items.length - 1];
  }

  // 移出栈顶的元素
  pop() {
    return this.items.pop();
  }
  
  /**
   * 判断栈是否为空
   */
  isEmpty() {
    return this.items.length <= 0;
  }
}

队列

队列遵循 先进先出 的原则。

/**
 * 队列
 * 先进先出
 */
class Queue {
  constructor() {
    this.items = [];
  }

  /**
   * 添加元素
   */
  enqueue(value) {
    this.items.push(value);
  }

  /**
   * 移出队列的第一个元素
   */
  dequeue() {
    return this.items.shift();
  }
}

常见题目

1. 有效的括号

问题描述

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

解题思路

使用 来解决。

  • 遍历字符串,如果是左括号便压入栈中。
  • 如果遇到右括号,分类谈论:
    1. 如果当前栈为空,返回 false
    2. 取出栈顶元素,如果与之匹配继续循环,否则返回 false
/**
 * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
 * @param {*} str
 */
function isValidStr(str) {
  let arr = str.split("");
  let stack = new Stack();

  function isMatchStr(a, b) {
    return (
      (a === "(" && b === ")") ||
      (a === "[" && b === "]") ||
      (a === "{" && b === "}")
    );
  }

  while (arr.length) {
    let char = arr.shift();

    if (char === "(" || char === "[" || char === "{") {
      stack.push(char);
    } else {
      if (stack.isEmpty()) {
        return false;
      } else if (isMatchStr(stack.pop(), char)) {
        continue;
      } else {
        return false;
      }
    }
  }

  return true;
}

2. 用两个栈实现队列

问题描述

用两个栈来实现一个队列,完成队列的 enqueuedequeue 操作。

解题思路

in 栈用于处理 入列 操作,out 栈用于处理 出列 操作。

  • 入列的值直接压入 in
  • 出列时,将 in 栈的元素出栈压入到 out 栈,然后返回 out 栈栈顶的元素(这样便保持了队列 先进先出 的原则)。
class TwoStackQueue {
  constructor() {
    this.inStack = new Stack();
    this.outStack = new Stack();
  }

  enqueue(value) {
    this.inStack.push(value);
  }

  dequeue() {
    while (!this.inStack.isEmpty()) {
      this.outStack.push(this.inStack.pop());
    }

    return this.outStack.pop();
  }
}

3. 栈的压入、弹出序列

问题描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解题思路

初始化一个辅助栈,遍历压入顺序,执行入栈操作,入栈的同时,如果辅助栈非空,同时弹出序列的当前值与辅助栈栈顶元素相同,则辅助栈出栈。最后判断辅助是否为空,为空这是正确的顺序,否则不是。例如:

入栈:1, 2, 3, 4, 5

出栈:4, 5, 3, 2, 1

首先,1 入栈,此时栈顶元素 1 != 4,继续入栈;

2 != 4,入栈;

3 != 4 入栈;

4 == 4,入栈后出栈(这时候栈内元素为 1, 2, 3);

3 != 5,入栈(这时候栈内元素为 1, 2, 3, 5),5 == 5 出栈,3 == 3 出栈...

最后栈为空,顺序匹配。

function isPopOrder(pushOrder, popOrder) {
  let stack = new Stack();
  let popIndex = 0;

  for (let pushIndex = 0; pushIndex < pushOrder.length; pushIndex++) {
    stack.push(pushOrder[pushIndex]);

    while (!stack.isEmpty() && stack.peek() === popOrder[popIndex]) {
      stack.pop();
      popIndex++;
    }
  }

  return stack.isEmpty();
}
@fantasticit fantasticit changed the title js 数据结构:栈和队列 栈和队列 Aug 2, 2019
@fantasticit fantasticit changed the title 栈和队列 前端学数据结构:栈和队列 Aug 4, 2019
@fantasticit fantasticit changed the title 前端学数据结构:栈和队列 JavaScript 数据结构:栈和队列 Aug 9, 2019
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant