Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant