JavaScript:栈和对列

文章介绍了如何在JavaScript中使用数组模拟栈和队列,以及在LeetCode题目中应用这些数据结构解决问题,如有效括号的匹配、删除字符串中的相邻重复项和逆波兰表达式的求值。文章还涉及了数组操作和JavaScript的isNaN()函数及位运算符。

栈和对列

Js 有栈与队列吗

[图片]

JavaScript 没有内置的栈和队列数据结构,但可以使用数组来模拟它们。

  1. 栈(Stack)
    栈是一种后进先出(LIFO)的数据结构。可以使用数组来实现栈,使用 push() 方法向栈顶添加元素,使用 pop() 方法弹出栈顶元素。
    push() 方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而 pop() 方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。
    例如:
    [图片]
// 入栈出栈---先进后出
const stack = [];

stack.push(1);
stack.push(2);
stack.push(3);

console.log(stack.pop()); // 3
console.log(stack.pop()); // 2
console.log(stack.pop()); // 1
  1. 队列(Queue)
    队列是一种先进先出(FIFO)的数据结构。可以使用数组来实现队列,使用 push() 方法向队尾添加元素,使用 shift() 方法弹出队头元素。
    例如:
    [图片]
// 入队出队---先进先出
const queue = [];

queue.push(1);
queue.push(2);
queue.push(3);

console.log(queue.shift()); // 1
console.log(queue.shift()); // 2
console.log(queue.shift()); // 3

需要注意的是,使用数组实现队列时,使用 shift() 方法弹出队头元素的时间复杂度为 O(n),因为需要将数组中所有元素向前移动一位。如果需要高效地实现队列,可以使用双端队列(deque)或循环队列(circular queue)。unshift()方法是向数组的开头添加一个或多个元素,并且返回新的长度。

20. 有效的括号 - 力扣(LeetCode)

思路

在这里插入图片描述

代码分析

/*
 * @lc app=leetcode.cn id=20 lang=javascript
 *
 * [20] 有效的括号
 */

// @lc code=start
/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
/* 
        如果是左括号,就把相应的右括号,push压入栈
        如果是右括号,就弹出当前栈的末尾元素pop,如果匹配,继续上述操作,不匹配返回false
        当遍历完所有的字符,栈里面位空,则返回true
     */
    /**
     * eg  ([(){}])
     * 技巧:我们匹配左括号的时候,可以让右括号入栈,这样就只需要比较当前元素和栈顶元素是否相等
     */
    // 1 建一个栈 数组
    const stack = []
    // 2 遍历字符串
    for(let i = 0; i < s.length; i++) {
        // 判断当前的括号是否是左括号,是左括号,入栈(push()),最后入的就是栈顶元素
        switch (s[i]) {
            case '(':
                stack.push(')')
                break;
            case '[':
                stack.push(']')
                break;
            case '{':
                stack.push('}')
                break;
            default:
                // 右括号,如果跟栈顶元素(pop())不相等,false
                if(s[i] !== stack.pop())
                return false
        }
    }
    // 当元素遍历完了,栈为空,那么返回true
    return stack.length === 0
};
// @lc code=end

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

思路

在这里插入图片描述

代码分析

/*
 * @lc app=leetcode.cn id=1047 lang=javascript
 *
 * [1047] 删除字符串中的所有相邻重复项
 */

// @lc code=start
/**
 * @param {string} s
 * @return {string}
 */
var removeDuplicates = function(s) {
    /**
     * 删除相邻相同的字符,重复删除直至无法删除(入栈出栈)
     */
    // 1 创建栈
    const stack = []
    // 2 遍历字符串
    for(const x of s) {
        // 使用c记录弹出的元素是否与当前遍历元素一样,不一样需要把c压回栈中
        let c = null
        // 3 栈不为空,且当前的字符 === 弹出的字符 跳出循环继续遍历
        if(stack.length && x === (c = stack.pop())) continue
        // 4 当前字符和弹出字符不一致时,且c存在(栈空的时候不存在),我们把c继续压入栈中,继续进行匹配
        c && stack.push(c)
        // 5 如果弹出字符没有与当前字符x相等,则把当前的x压入栈
        stack.push(x)
    }
    // 6 返回当前栈 且去掉分隔符
    return stack.join("")
};
// @lc code=end

array.join() 操作打印

[图片]
[图片]

const s of str 操作遍历

[图片]

150. 逆波兰表达式求值 - 力扣(LeetCode)

思路

在这里插入图片描述

代码分析

/*
 * @lc app=leetcode.cn id=150 lang=javascript
 *
 * [150] 逆波兰表达式求值
 */

// @lc code=start
/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function(tokens) {
    /**
     * 逆波兰:后序遍历,我们需要得到正常的表达式(中序遍历,左根右)来计算
     * 思路:遇到数字,入栈,遇到符号,我们就弹出两个数字n2,n1,进行计算,再把结果压入栈,之后继续判断是否遇到数字还是符号
     */
    // 1 创建栈
    const stack = []
    // 2 遍历字符串
    for(const token of tokens) {
        // 3 如果是数字(需要把字符串强制转成数字类型),压入栈
        if(!isNaN(Number(token))) {
            stack.push(Number(token))
        }else {
            // 4 不是数字,弹出两个数字,判断符号,再进行运算,结果压入栈,继续判断是否是数字
            const n2 = stack.pop()
            const n1 = stack.pop()
            switch (token) {
                case '+':
                    stack.push(n1 + n2)
                    break;
                case '-':
                    stack.push(n1 - n2)
                    break;
                case '*':
                    stack.push(n1 * n2)
                    break
                case '/':
                    // 取整操作 | 0 保留整数部分
                    // stack.push(n1 / n2 | 0)
                    stack.push(parseInt(n1/n2))
                    break
                default:
                    break;
            }
        }
    }
    // 5 直到最后计算完全部,压入的最后一个值,就是最终结果
    return stack[0]

};
// @lc code=end

js:isNaN()

JavaScript isNaN() 函数
isNaN()是JavaScript中的一个函数,用于检查一个值是否是非数字NaN(Not a Number)。
语法:
isNaN(value)
参数:
value:需要检查的值。
返回值:
如果value是NaN,返回true;否则返回false。
示例:

isNaN(123) // false
isNaN('123') // false
isNaN('hello') // true
isNaN('') // false
isNaN(null) // false
isNaN(undefined) // true
isNaN(NaN) // true

注意:如果参数不是数值类型,isNaN()会尝试将其转换为数值类型,如果无法转换,则返回true。例如,字符串'hello'无法转换为数值类型,所以isNaN('hello')返回true。

JavaScript 位运算符 |

JavaScript 运算符 | 菜鸟教程
JavaScript 取整函数_js 取整_不见舟的博客-优快云博客
javascript位运算技巧(有点错误可在控制台检测)
[图片]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值