网站首页 > 文章精选 正文
题目难度: 中等
原题链接[1]
今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~
题目描述
给定一个二叉树 根节点 root ,树的每个节点的值要么是 0,要么是 1。请剪除该二叉树中所有节点的值为 0 的子树。
节点 node 的子树为 node 本身,以及所有 node 的后代。
示例 1:
- 输入: [1,null,0,0,1]
- 输出: [1,null,0,null,1]
- 解释: 只有红色节点满足条件“所有不包含 1 的子树”。 右图为返回的答案。
示例 2:
- 输入: [1,0,1,0,0,0,1]
- 输出: [1,null,1,null,1]
- 解释:
示例 3:
- 输入: [1,1,0,1,1,0,1,0]
- 输出: [1,1,0,1,1,null,1]
- 解释:
提示:
- 二叉树的节点个数的范围是 [1,200]
- 二叉树节点的值只会是 0 或 1
题目思考
- 如何在得到子树所有节点值的同时, 进行剪除操作?
解决方案
思路
- 分析题目, 如果某个子树的所有节点都是 0, 则其根节点的值为 0, 且左右子树的所有节点也都是 0
- 我们可以根据这一点, 使用 DFS 来判断, 具体做法如下:
- dfs 函数传入节点 node 作为参数, 返回以该节点为根的子树的所有节点是否全为 0
- 如果传入是空节点, 则返回 true, 作为递归出口
- 否则先递归调用 dfs 函数, 传入其左右子节点, 从而得到左右子树是否全为 0 的两个布尔值: leftAllZero 和 rightAllZero
- 那么当前子树要想全为 0, 就需要 node.val==0 && leftAllZero && rightAllZero, 返回它即可
- 上述步骤只是得出了每个子树的所有节点是否全 0, 题目还要求剪除全 0 子树, 如何操作呢?
- 我们可以在上面的第三步和第四步之间加入剪除操作:
- 如果左子树全 0, 就断开当前节点和其左子节点的连接
- 如果右子树全 0, 就断开当前节点和其右子节点的连接
- 这样就在得到子树所有节点值的同时, 进行了剪除操作
- 需要注意有可能整棵树的所有节点全为 0, 此时剪除后需要返回空节点
- 我们可以引入一个哨兵节点, 将其左子节点指向整棵树的根节点
- 然后从哨兵节点开始判断, 最终返回哨兵的左子节点, 这样就无需针对根节点做特殊处理了
- 下面的代码就对应了上面的整个过程, 并且有详细的注释, 方便大家理解
复杂度
- 时间复杂度 O(N): 需要遍历每个节点一遍
- 空间复杂度 O(H): H 是树的高度, 也是递归栈的空间消耗
代码
class Solution:
def pruneTree(self, root: TreeNode) -> TreeNode:
# 使用哨兵节点, 将其左子节点指向root, 并从哨兵开始判断
# 因为有可能整个树都是0, 此时需要返回空节点, 如果不用哨兵从root开始判断, 就需要额外的逻辑特殊处理root
dummy = TreeNode(0, root)
def allZero(node):
if not node:
# 递归出口, 空节点的值不是1, 所以返回True
return True
leftAllZero = allZero(node.left)
rightAllZero = allZero(node.right)
if leftAllZero:
# 左子树全为0, 断开当前节点与其的连接
node.left = None
if rightAllZero:
# 右子树全为0, 断开当前节点与其的连接
node.right = None
# 当前子树全为0需要满足: 当前节点值为0 && 左子树全为0 && 右子树全为0
return node.val == 0 and leftAllZero and rightAllZero
allZero(dummy)
# 最终哨兵节点的左子节点即为删除全0子树后的根节点 (可能为空)
return dummy.left
参考资料
[1]
原题链接: https://leetcode.cn/problems/pOCWxh
猜你喜欢
- 2024-12-29 剑指Offer (十五):反转链表(Java版)
- 2024-12-29 剑指offer刷题(八)(56-60)题 剑指offer62题
- 2024-12-29 剑指OfferII016.不含重复字符的最长子字符串
- 2024-12-29 剑指OfferII086.分割回文子字符串
- 2024-12-29 剑指offer刷题(一)(1-20)题 剑指offer刷完什么水平
- 2024-12-29 剑指OfferII110.所有路径 剑指offer在哪
- 2024-12-29 LeetCode—剑指 Offer 47. 礼物的最大价值
- 2024-12-29 429,剑指 Offer-删除链表的节点 删除链表中的节点
- 2024-12-29 《剑指Offer》- 连续子数组的最大和或最小和
- 2024-12-29 剑指Offer Golang 实现合并区间算法
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)