《剑指 Offer》专项突破版 - 面试题 47 : 二叉树剪枝(C++ 实现)

题目链接LCR 047. 二叉树剪枝 - 力扣(LeetCode)

题目

一棵二叉树的所有节点的值要么是 0 要么是 1,请剪除该二叉树中所有节点的值全都是 0 的子树。例如,在剪除下图 (a) 中二叉树中所有节点值都为 0 的子树之后的结果如下图 (b) 所示。

分析

首先分析哪些子树会被剪除,哪些子树不能被剪除。在上图 (a) 的二叉树中,以第 2 层第 1 个节点为根节点的子树的 3 个节点的值都是 0,因此整棵二叉树都被剪除。以第 2 层第 2 个节点为根节点的子树中有一个节点的值是 1(第 3 层第 4 个节点),因此这棵子树不能删除,但是它的左子树(根节点为第 3 层第 3 个节点)只有一个节点并且值为 0,因此它的左子树可以被剪除。

下面总结什么样的节点可以被删除。首先,这个节点的值应该是 0。其次,如果它有子树,那么它的子树的所有节点的值都为 0。也就是说,如果一个节点可以被删除,那么它的子树的所有节点都可以被删除。例如,在上图 (a) 的二叉树中,第 2 层第 1 个节点可以被删除,它的子树中的所有节点(第 3 层第 1 个节点和第 2 个节点)也可以被删除。

由此发现,后序遍历 最适合用来解决这个问题。如果用后序遍历的顺序遍历到某个节点,那么它的左右子树的节点一定已经遍历过了。每遍历到一个节点,就要确定它是否有左右子树,如果左右子树都是空的,并且节点的值是 0,那么就可以删除这个节点。

代码实现

cpp 复制代码
class Solution {
public:
    TreeNode* pruneTree(TreeNode* root) {
        if (!root)
            return nullptr;
        
        root->left = pruneTree(root->left);
        root->right = pruneTree(root->right);
        if (!root->left && !root->right && root->val == 0)
            return nullptr;
        
        return root;
    }
};
相关推荐
划破黑暗的第一缕曙光1 分钟前
[C++]:2.类和对象(上)
c++·类和对象
季明洵4 分钟前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi9 分钟前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL9 分钟前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独
Yeats_Liao10 分钟前
评估体系构建:基于自动化指标与人工打分的双重验证
运维·人工智能·深度学习·算法·机器学习·自动化
墨雪不会编程11 分钟前
C++之【深入理解Vector】三部曲最终章
开发语言·c++
cpp_250114 分钟前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-18 分钟前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
kyle~20 分钟前
ROS2---QoS策略
c++·机器人·ros2
小宋102129 分钟前
Java 项目结构 vs Python 项目结构:如何快速搭一个可跑项目
java·开发语言·python