训练营Day11 栈和队列

20. 有效的括号

力扣题目链接

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

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:

输入: "()"
输出: true
括号匹配是使用栈解决的经典问题。
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

括号匹配1

 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。

 括号匹配2

 第二种情况,括号没有多余,但是 括号的类型没有匹配上

 括号匹配3

 第三种情况,字符串里右方向的括号多余了,所以不匹配

 

var s="()"
var isValid = function(s) {
    var stack = []
    var map = {
        '(':')',
        '[':']',
        '{':'}'
    }
    for(var i=0;i<s.length;i++){
        if(s[i] in map){
            stack.push(s[i])
        }else{
            var top = stack.pop()
            if(map[top] != s[i]){
                return false
            }
        }
    }
    if(stack.length != 0){
        return false
    }
    return true
};
console.log(isValid(s))

var isValid = function (s) {
    const stack = [];
    for (let i = 0; i < s.length; i++) {
      let c = s[i];
      switch (c) {
        case '(':
          stack.push(')');
          break;
        case '[':
          stack.push(']');
          break;
        case '{':
          stack.push('}');
          break;
        default:
          if (c !== stack.pop()) {
            return false;
          }
      }
    }
    return stack.length === 0;
  };
  // 简化版本
  var isValid = function(s) {
      const stack = [], 
          map = {
              "(":")",
              "{":"}",
              "[":"]"
          };
      for(const x of s) {
          if(x in map) {
              stack.push(x);
              continue;
          };
          if(map[stack.pop()] !== x) return false;
      }
      return !stack.length;
  };

 

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

力扣题目链接

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"
输出:"ca"
解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:

1 <= S.length <= 20000
S 仅由小写英文字母组成。
#思路

 

 

var tokens=["2", "1", "+", "3", "*"];
var evalRPN = function(tokens) {
    let stack = [];
    for(let i = 0; i < tokens.length; i++){
        if(tokens[i] === '+'){
            let a = stack.pop();
            let b = stack.pop();
            stack.push(a + b);
        }else if(tokens[i] === '-'){
            let a = stack.pop();
            let b = stack.pop();
            stack.push(b - a);
        }else if(tokens[i] === '*'){
            let a = stack.pop();
            let b = stack.pop();
            stack.push(a * b);
        }else if(tokens[i] === '/'){
            let a = stack.pop();
            let b = stack.pop();
            stack.push(b / a | 0);//b / a | 0的意思是取整
        }else{
            stack.push(Number(tokens[i]));
        }
    }
    return stack.pop();
}
console.log(evalRPN(tokens));

var evalRPN = function (tokens) {
    const stack = [];
    for (const token of tokens) {
        if (isNaN(Number(token))) { // 非数字
            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 "/":
                    stack.push(n1 / n2 | 0);
                    break;
            }
        } else { // 数字
            stack.push(Number(token));
        }
    }
    return stack[0]; // 因没有遇到运算符而待在栈中的结果
};

 

150. 逆波兰表达式求值

力扣题目链接

 

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + ,  - ,  * ,  / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

输入: ["2", "1", "+", "3", " * "]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:

输入: ["4", "13", "5", "/", "+"]
输出: 6
解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:

输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"]

输出: 22

 

var input="abbaca";
var removeDuplicates = function(S) {
    let stack = [];
    for(let i = 0; i < S.length; i++){
        if(stack.length === 0 || stack[stack.length - 1] !== S[i]){
            stack.push(S[i]);
        }else{
            stack.pop();
        }
    }
    return stack.join('');
};
console.log(removeDuplicates(input));


// 法一:使用栈
var removeDuplicates = function(s) {
    const stack = [];
    for(const x of s) {
        let c = null;
        if(stack.length && x === (c = stack.pop())) continue;
        c && stack.push(c);
        stack.push(x);
    }
    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]) { // top === -1 即空栈
            s[++top] = s[i]; // 入栈
        } else {
            top--; // 推出栈
        }
    }
    s.length = top + 1; // 栈顶元素下标 + 1 为栈的长度
    return s.join('');
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值