【代码随想录算法训练营】D11 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

今日题目:

  • 20. 有效的括号
  • 1047. 删除字符串中的所有相邻重复项
  • 150. 逆波兰表达式求值

解题思想:

  1. 括号匹配

由于栈结构的特殊性,非常适合做对称匹配的问题。我们在解题的时候,可以利用map存储匹配的括号,当遍历遇到左括号时,把右括号压进栈,当遇到右括号时,从栈中弹出元素判断是否与遍历到的元素相等。这样毕直接左括号入栈实现要简单明了很多。注意最后还要判断栈是否为空。

  1. 删除字符串中的所有相邻重复项

本题复杂之处在于,不仅要招相邻的重复项,相邻的重复项删除之后,又有新的黏连项,要判断是否需要继续删除。但思路还是一样,用栈来存储判断。也可以用双指针来模拟栈,原地解题,一个指针一直指向栈顶元素,另一个指针指向遍历的元素,不断对比移动。

  1. 逆波兰式

逆波兰表达式相当于二叉树中的后序遍历。在本题中,每一个表达式要得到一个结果,然后拿这个结果再进行运算,遍历到数字的时候就压入栈,遍历到运算符号的时候就从栈中取数字,再把此结果压入栈。
但这道题有很多小细节需要注意,可以用Map数据格式存储运算表达式与对应的算式回调函数。这样更有利于对每个算数的情况进行细节把控:+号运算注意隐式转换为数字(防止变为字符串相加),除号还要做情况讨论,同时要注意操作数的顺序,因为是栈要倒过来。不然会出错。


代码:

  • 20 . 有效的括号
var isValid = function(s) {
    const map = new Map
    map.set("{","}")
    map.set("[","]")
    map.set("(",")")

    const stack = []

    for(let i = 0; i< s.length; i++) {
        if(map.has(s[i])) {
            stack.push(map.get(s[i]))
        } else {
            if(s[i] !== stack.pop()) return false
        }
    }


    if(stack.length !== 0) return false
    return true
};
  • 1047 . 删除字符串中的所有相邻重复项
var removeDuplicates = function(s) {
    const stack = [s[0]]
    let pre 

    for(let i = 1; i<s.length; i++) {
        pre = stack.pop() || undefined
        if(s[i] == pre) continue
        else {
            stack.push(pre)
            stack.push(s[i])
            pre = s[i]
        }
    }

    return stack.join('')
};

//原地双指针
var removeDuplicates = function(s) {
    s = [...s]
    let top = -1 //栈顶下标
    for(let i = 0; i<s.length; i++) {
        if(top === -1 || s[top] !== s[i]) {
            s[++top] = s[i] //入栈
        } else {
            top--
        }
    }

    s.length = top+1
    return s.join('')
};
  • 150 . 逆波兰表达式求值
var evalRPN = function(tokens) {
    const s = new Map([
        ["+",(a,b) => a*1 + b*1],   //这里注意一定要乘以1,不然相当于字符串相加了
        ["-",(a,b) => b-a],  //注意顺序是b-a
        ["*",(a,b) => b*a],
        ["/",(a,b) => (b/a) | 0]   //这里要 |0操作,不然涉及到除法的会出错
    ])

    const stack = []
    for(const i of tokens) {
        if(!s.has(i)) {
            stack.push(i)
            continue
        }
        stack.push(s.get(i)(stack.pop(), stack.pop()))
    }
    return stack.pop()
};

总结:

1047题双指针来模拟栈的做法还蛮有意思的,注意最后要控制数组的长度。逆波兰表达式其实不难,但是细节很多,自己做的时候一直不知道问题出现在哪,看了代码随想录给的代码确实巧妙优雅,用map不仅来存储符号,还存储对应的回调函数,并且这样操作能更好处理操作数之间的顺序、隐式转换为数字、对除法做特殊处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值