JS 算法分享——[LeetCode]验证栈序列

163 阅读1分钟

题目:946.验证栈序列

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 

示例一;

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]

输出:true

解释:我们可以按以下顺序执行:

push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例二;

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]

输出:false

解释:1不能在2之前弹出。

本题来源于leetcode

解题思路

规律: popped中的后一位必须是pushed中当前值的前一位或者未出现过的数。

前提条件: 判断后的数字从pushed中移除。

思路:

  • 需要一个空栈模拟操作
  • 取popped第一位判断是否在pushed中
  • pushed中当前值之前所有都放入新栈中
  • popped中下一位是否等于新栈的栈顶或者还未入栈时
  • 当值还未入栈时
  • 当popped中下一位是栈顶时,结束

代码实现:

var validateStackSequences = function (pushed, popped) {
    if (popped.length !== pushed.length || popped.length == 0 || pushed.length == 0) return false;

    let newStack = [];
    let index = -1;
    for (let i = 0; i < popped.length; i++) {
        // 空栈或者在栈外(不在栈顶时默认栈外),未入栈则将之前的元素全部入栈
        if (newStack.length == 0 || popped[i] !== newStack[newStack.length - 1]) {
            // 入栈
            do {
                // 记录入栈的位置
                index++;

                newStack.push(pushed[index]);
            } while (pushed[index] !== popped[i] && index < popped.length);
        }

        // 判断是否为栈顶,是则pop,否则返回false
        if (newStack[newStack.length - 1] !== popped[i]) {
            return false;
        } else {
            newStack.pop();
        }
    }

    // 循环结束返回true
    return true;
};

const res = validateStackSequences([2, 3, 4, 5], [4, 3, 5, 2, 1]);
console.log(res);