【Leetcode】1106. Parsing A Boolean Expression

题目地址:

https://leetcode.com/problems/parsing-a-boolean-expression/

给定一个表达式,该表达式是个类似于前缀表达式的布尔表达式,其中't'代表true,'f'代表false,其定义是递归的:
1、单个't'或者'f'是个表达式;
2、如果expr是个表达式,则'!(expr)''&(expr,expr,...)''|(expr,expr,...)'都是个表达式。
求该表达式的值。

思路和表达式求值类似,只不过这里不需要考虑优先级的问题。开两个栈,一个存操作数(即't''f')以及左括号'('(这是因为要标记一下做运算的操作数是哪些),另一个存操作符(即'!''&''|')。遇到逗号则直接跳过。遇到右括号的时候开始计算,先pop出操作符和一个操作数,如果操作符是'!',则直接将那个操作数取非入操作数栈(当然要先把左括号pop掉再入栈);如果操作符是另外两个,则将操作数的最上面的左括号之上的所有数进行那个运算,再pop出左括号,再将计算结果入栈。最后操作数栈内就保存了运算答案。代码如下:

class Solution {
 public:
  bool parseBoolExpr(string e) {
    stack<char> ops, stk;
    for (int i = 0; i < e.size(); i++) {
      char ch = e[i];
      if (ch == ',') continue;
      if (ch == '|' || ch == '&' || ch == '!') ops.push(ch);
      else if (ch == '(' || ch == 't' || ch == 'f') stk.push(ch);
      else {
        // 此时ch是')',需要求解
        char op = ops.top(); ops.pop();
        char x = stk.top(); stk.pop();
        bool cur = x == 't';
        if (op == '!') {
          // pop掉'('
          stk.pop();
          stk.push(cur ? 'f' : 't');
        } else {
          while (stk.top() != '(') {
            op == '&' ? cur &= stk.top() == 't' : cur |= stk.top() == 't';
            stk.pop();
          }

          stk.pop();
          stk.push(cur ? 't' : 'f');
        }
      }
    }

    return stk.top() == 't';
  }
};

时空复杂度 O ( n ) O(n) O(n) n n n是表达式长度。

也可以用递归来做。代码如下:

class Solution {
 public:
  bool dfs(int &k, string& s) {
    if (s[k] == 't') {
      k++;
      return true;
    }
    if (s[k] == 'f') {
      k++;
      return false;
    }
    char op = s[k];
    k += 2;
    
    bool res = op == '&';
    while (s[k] != ')') {
      if (s[k] == ',') k++;
      else {
        bool t = dfs(k, s);
        if (op == '&') res &= t;
        else res |= t;
      }
    }

    k++;
    if (op == '!') res = !res;
    return res;
  }

  bool parseBoolExpr(string e) {
    int k = 0;
    return dfs(k, e);
  }
};

时空复杂度一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值