JavaScript算法之栈

113 阅读2分钟

栈是一个后进先出的数据结构。

JavaScript中没有栈,但可以使用Array实现栈的所有功能。

const stack=[];
stack.push(1);
stack.push(2);
const item1=stack.pop();
const item2=stack.pop();

入栈:push()

出栈:pop()

获取栈顶元素:array[array.length-1]

栈的应用场景

后进先出的场景:十进制转二进制,判断字符串的括号是否有效,函数调用堆栈......

十进制转二进制

图片.png

后出来的余数反而要排到前面。

把余数依次入栈,然后再出站,就可以实现余数的倒序输出。

有效的括号

题目描述:

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

有效字符串需满足:

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

示例 1:

输入:s = "()" 输出:true

示例 2:

输入:s = "()[]{}" 输出:true

示例 3:

输入:s = "(]" 输出:false

示例 4:

输入:s = "([)]" 输出:false

题目链接: leetcode第20题

题目解析:

越靠后的左括号,对应的右括号就越靠前。

:(先进后出,后遍历的左括号先被右括号所匹配)

  1. 新建一个栈(数组)

  2. 遍历字符串,遇到左括号则进栈,遇到右括号与栈顶的左括号相匹配则栈顶的左括号出栈,右括号没有匹配的左括号,则判断为不合法。

  3. 若遍历结束后,栈为空则合法,栈不为空则代码栈中存在左括号没有匹配的右括号,判断为不合法。

注:由于括号为两两配对,则合法的括号字符串的长度一定为偶数,则若字符串长度为奇数时,判断为不合法。

var isValid = function(s) {
    //新建栈
    const stack=[]; 
    //字符串长度为奇数则不合法
    if(s.length%2===1) return false;
    //遍历字符串的字符 
    for(let i=0;i<s.length;i++){
        const c=s[i];
        //为左括号则入栈
        if(c==='('||c==='{'||c==='['){
            stack.push(c)
        }else{
        //为右括号则判断是否与栈顶元素所匹配
            const l=stack[stack.length-1];
            if((c===')'&&l==='(')||
            (c==='}'&&l==='{')||
            (c===']'&&l==='[')){
            //匹配则将栈顶元素出栈
                stack.pop()
            }else{
                return false;
            }
        }
    }
    //栈为空则有效,栈不为空则为不合法
    return stack.length===0;
};

时间复杂度:O(n) 遍历字符串,for循环中代码执行n次

空间复杂度:O(n) 最坏情况下会有n个元素进栈,占用n个空间(字符串中全为左括号)

函数调用堆栈

图片.png

调用函数时,最后调用的函数最先执行完;最先调用的函数最后执行完(因为调用一个函数后该函数的执行则需要将该函数函数内部嵌套的其他函数调用并执行完成之后才能结束)。

js解释器使用栈来控制函数的调用顺序。