返回

剑指Offer——栈的压入、弹出序列(JS实现)

前端

        # 标题
        

        # 关键词
        

        # 
        

        # 正文

        ## 前言

        作为一名程序员,我们经常会遇到各种各样的数据结构。其中,栈是一种非常重要的数据结构,它遵循后进先出的原则(LIFO),即最后压入的数据会最先弹出。在现实生活中,栈有很多应用场景,例如:

        - 浏览器的前进和后退按钮
        - 函数调用
        - 编译器中的符号表

        ## 题目

        剑指Offer中有一道经典题目“栈的压入、弹出序列”,题目描述如下:

        > 给定一个压入栈的序列,判定是否有一个栈能够由这个序列所生成。该栈中只能包含整数,初始情况下为空。每次给出的整数描述一个基本操作,要么把该整数压入栈中,要么把栈顶的整数弹出。

        **示例 1:** 

        ```
        pushed = [1, 2, 3, 4, 5]
        popped = [4, 5, 3, 2, 1]
        ```

        **输出:** true

        **解释:** 我们可以模拟栈的操作过程:

        ```
        push(1)
        push(2)
        push(3)
        push(4)
        push(5)
        pop() // 5
        pop() // 4
        pop() // 3
        pop() // 2
        pop() // 1
        ```

        可以看出,压入、弹出序列[1, 2, 3, 4, 5]和[4, 5, 3, 2, 1]是可行的。

        **示例 2:** 

        ```
        pushed = [1, 2, 3, 4, 5]
        popped = [4, 3, 5, 1, 2]
        ```

        **输出:** false

        **解释:** 我们可以模拟栈的操作过程:

        ```
        push(1)
        push(2)
        push(3)
        push(4)
        push(5)
        pop() // 5
        pop() // 4
        pop() // 3
        pop() // 1
        pop() // 2
        ```

        可以看出,当我们尝试弹出元素2时,栈中已经为空了。因此,压入、弹出序列[1, 2, 3, 4, 5]和[4, 3, 5, 1, 2]是不可行的。

        ## 解题思路

        本题的思想在于想到模拟栈,我们可以定义一个数组用来模拟栈,从pushed数组的第一个元素开始进行入栈,如果该元素在popped数组中,则进行出栈操作。如果该元素不在popped数组中,则入栈失败,返回false。如果所有元素都入栈成功,则返回true。

        ## 代码实现

        ```javascript
        /**
         * 判断一个压入、弹出序列是否可行
         *
         * @param {number[]} pushed 压入栈的序列
         * @param {number[]} popped 弹出栈的序列
         * @return {boolean}
         */
        const validateStackSequence = (pushed, popped) => {
          const stack = [];
          let i = 0;
          let j = 0;

          while (i < pushed.length) {
            stack.push(pushed[i]);
            while (stack.length > 0 && stack[stack.length - 1] === popped[j]) {
              stack.pop();
              j++;
            }
            i++;
          }

          return stack.length === 0;
        };
        ```

        ## 分析

        在上面的代码中,我们首先定义了一个名为stack的空数组,用来模拟栈。然后,我们使用两个指针i和j来分别遍历pushed数组和popped数组。

        对于pushed数组中的每个元素,我们将其压入栈中。然后,我们检查栈顶元素是否与popped数组中的当前元素相等。如果相等,则说明该元素可以被弹出,因此我们将其弹出栈中并更新指针j。如果栈顶元素与popped数组中的当前元素不相等,则说明该元素无法被弹出,因此我们返回false。

        当我们遍历完pushed数组后,如果栈中没有元素了,则说明所有元素都可以被弹出,因此我们返回true。否则,我们返回false。

        ## 总结

        在本文中,我们讨论了剑指Offer中经典题目“栈的压入、弹出序列”的解法。我们使用JavaScript实现了一个模拟栈的算法,并对代码进行了详细的分析。希望这篇博文对您有所帮助!