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

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 题目意思很简单让你去判断与或非布尔表达式的结果,我们可以看布尔表达式看成一棵树,需要我们解决的是从最底层的嵌套布尔表达式产生的结果不断向上的结果

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),不需要申请额外的空间
目录
相关文章
|
8月前
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
491 90
|
9月前
|
存储 自然语言处理 算法
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
本文详细解析了力扣热题 208——实现 Trie(前缀树)。Trie 是一种高效的树形数据结构,用于存储和检索字符串集合。文章通过插入、查找和前缀匹配三个核心操作,结合 Go 语言实现代码,清晰展示了 Trie 的工作原理。时间复杂度为 O(m),空间复杂度也为 O(m),其中 m 为字符串长度。此外,还探讨了 Trie 的变种及应用场景,如自动补全和词典查找等。适合初学者深入了解 Trie 结构及其实际用途。
281 14
|
10月前
|
网络协议 Linux Go
自己动手编写tcp/ip协议栈1:tcp包解析
学习tuntap中的tun的使用方法,并使用tun接口解析了ip包和tcp包,这是实现tcp/ip协议栈的第一步。
258 15
|
自然语言处理 算法 Python
再谈递归下降解析器:构建一个简单的算术表达式解析器
本文介绍了递归下降解析器的原理与实现,重点讲解了如何使用Python构建一个简单的算术表达式解析器。通过定义文法、实现词法分析器和解析器类,最终实现了对基本算术表达式的解析与计算功能。
343 52
|
网络协议
网络通信的基石:TCP/IP协议栈的层次结构解析
在现代网络通信中,TCP/IP协议栈是构建互联网的基础。它定义了数据如何在网络中传输,以及如何确保数据的完整性和可靠性。本文将深入探讨TCP/IP协议栈的层次结构,揭示每一层的功能和重要性。
767 5
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
1587 2
|
数据格式
常用的Lambda表达式案例解析,工作中都会用到!
常用的Lambda表达式案例解析,工作中都会用到!
171 2
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
97 0
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
97 0
|
存储 C++
栈的深度解析:顺序栈与链栈的实现
栈的深度解析:顺序栈与链栈的实现

热门文章

最新文章

推荐镜像

更多
  • DNS