Leetcode-每日一题1106. 解析布尔表达式(DFS模拟栈)

简介: 题目意思很简单让你去判断与或非布尔表达式的结果,我们可以看布尔表达式看成一棵树,需要我们解决的是从最底层的嵌套布尔表达式产生的结果不断向上的结果

66c2388c5dc04db1826607589cf3eb9b.png


题目链接:点击跳转


思路


方法一、DFS模拟栈


题目意思很简单让你去判断与或非布尔表达式的结果,我们可以看布尔表达式看成一棵树,需要我们解决的是从最底层的嵌套布尔表达式产生的结果不断向上的结果,如图:


b1c2d0e7fd314911b5d3073cf1af3a28.png


既然他是一棵树且我需要从叶结点往上,肯定能看出来直接用DFS遍历树不就好了吗,接下来要解决的问题就是怎么区分他的每个结点:


  • 如果是t、r则我们直接返回结果。


  • 在&、|布尔表达式中存在多个结点(内部表达式),每个结点(内部表达式)用,分割,需要注意我们不能直接用,来区分,因为可能存在嵌套的子树(内部表达式)那表达式怎么区分呢?


。其实仔细一看这不就是括号匹配么 ,我们用栈不就可以解决了么!

。所以我们只需要建立两个变量lcnt,rcnt分别表示左括号数量和右括号数量


  • 如果 lcnt - 1 == rcnt,表示当前这个内部表达式是一颗嵌套的子树。用DFS递归去解决


  • 如果 lcnt == rcnt,表示我们这个内部表达式已经结束了,用DFS递归去解决最后一个结点即可,将产生的结果向上传递返回。


  • 在&的布尔表达式中,如果出现了一个false那整个表达式就是false,我们可以用标记记录即可。


  • 在|的布尔表达式中,如果出现了一个true那整个表达式就是true,我们可以用标记记录即可。


  • 剩下的细节完善一下即可。


代码示例


func parseBoolExpr(s string) bool {
  if s[0] == 't' {
    return true
  } else if s[0] == 'f' {
    return false
  } else if s[0] == '!' {
    if parseBoolExpr(s[2:]) {
      return false
    } else {
      return true
    }
  } else if s[0] == '&' {
    l, r, lcnt, rcnt, f := 2, 2, 1, 0, 1
    for lcnt != rcnt && r < len(s) {
      if s[r] == ',' && lcnt-1 == rcnt {
        if !parseBoolExpr(s[l:r]) {
          f = 0
        }
        l = r + 1
      } else if s[r] == '(' {
        lcnt++
      } else if s[r] == ')' {
        rcnt++
        if lcnt == rcnt {
          if !parseBoolExpr(s[l:r]) {
            f = 0
          }
        }
      }
      r++
    }
    if f == 1 {
      return true
    } else {
      return false
    }
  } else if s[0] == '|' {
    l, r, lcnt, rcnt, f := 2, 2, 1, 0, 0
    for lcnt != rcnt && r < len(s) {
      if s[r] == ',' && lcnt-1 == rcnt {
        if parseBoolExpr(s[l:r]) {
          f = 1
        }
        l = r + 1
      } else if s[r] == '(' {
        lcnt++
      } else if s[r] == ')' {
        rcnt++
        if lcnt == rcnt {
          if parseBoolExpr(s[l:r]) {
            f = 1
          }
        }
      }
      r++
    }
    if f == 1 {
      return true
    } else {
      return false
    }
  }
  return true
}

f18d7e3e81db475bb1711750512f269b.png


复杂度分析


  • 时间复杂度:O(n),其中n表示 s 字符串的长度,遍历一遍字符串需要O(n)的时间。
  • 空间复杂度:O(1),不需要申请额外的空间
目录
相关文章
LeetCode 热题100——单调栈
LeetCode 热题100——单调栈
19 0
|
2月前
|
Go C++
【力扣】2696. 删除子串后的字符串最小长度(模拟 栈 C++ Go实现栈)
【2月更文挑战第18天】2696. 删除子串后的字符串最小长度(模拟 栈 C++ Go实现栈)
34 6
|
3月前
|
并行计算 Java 程序员
深入解析JDK 8中的Lambda表达式:新特性的力量
本文将深入探讨JDK 8中引入的最引人注目的新特性之一:Lambda表达式。我们将详细解析Lambda表达式的概念、语法和用途,并通过实际示例展示如何利用Lambda表达式简化代码和提高编程效率。
|
4月前
【Leetcode 2487】从链表中移除节点 —— 单调栈
解题思路:维持一个单调递增栈,当栈为空时,记录当前节点为头节点;否则当前节点为栈顶节点的后继节点
|
4月前
【Leetcode 1944】队列中可以看到的人数 —— 单调栈
解题思路:维持一个单调递增栈来辅助计算每个人能够看到的人数。从右往左遍历数组,对于每个人,我们将其身高与栈顶元素的身高进行比较。如果当前人的身高比栈顶元素的身高高,则栈顶元素无法被当前人看到,将其出栈,并累计计数
|
2月前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
74 1
LeetCode | 232. 用栈实现队列
LeetCode | 232. 用栈实现队列
|
15天前
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
[leetcode~dfs]1261. 在受污染的二叉树中查找元素
|
23天前
|
算法 定位技术
【leetcode】剑指 Offer II 105. 岛屿的最大面积-【深度优先DFS】
【leetcode】剑指 Offer II 105. 岛屿的最大面积-【深度优先DFS】
17 0
|
2月前
|
Java 开发者
深入解析Java中的Lambda表达式
本文深入探讨Java编程语言中的Lambda表达式,介绍了Lambda表达式的定义、优势以及在实际开发中的应用场景,旨在帮助读者更好地理解和运用这一特性。

热门文章

最新文章

推荐镜像

更多