后序之二叉树裁剪

Posted Yuning算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后序之二叉树裁剪相关的知识,希望对你有一定的参考价值。

今天再讲一道二叉树的后续遍历


A

题目描述


本题leetcode地址:https://leetcode-cn.com/problems/binary-tree-pruning/

给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1。
返回移除了所有不包含 1 的子树的原二叉树。

题目的意思就是: 删除所有不包含1的子树。怎么删除?其实就是子树置空即可。

如上图:题目意思很好理解,就是找出只包含0的子树,然后置空即可



B

题目分析


要想知道子树是否全是0,或者换个方式理解,子树是否包含1。这种遍历方式不难想到是后序遍历,因为后序遍历是先遍历子树,再遍历自己。因此首先后序遍历先确定下来。


其次,需要确定子树是否包含1,我们这样处理:


如果当前是叶节点,那么我们返回一个bool值,当叶节点是1时,返回true表示该子树包含1。反之返回0。


当该节点是空节点时,返回false,空节点不包含1


那么根节点根据返回值来判断左右子树是否包含1,进而来确定是否删除左右子树。


定义一个helper函数:返回值是bool 表示该子树是否包含1,如果包含1返回true。否则返回false


递归的base case:

如果root == null,直接返回false即可,因为空子树不包含1

如果root 是叶节点,返回 root.val == 1


当递归返回时:

    如果左子树返回false,表示不包含1,那么 root.left = null 即可

    如果右子树返回false,表示不包含1,那么root.right = null 即可

    当前节点的返回值:左孩子包含1    ||  右孩子包含1  || 节点本身是1 


过程如下:

后序之二叉树裁剪

同理,该节点想知道右孩子是否包含1,递归调用右孩子,获取结果。
右孩子是叶节点,返回true。此时root知道右孩子包含1,保留右孩子。
该节点自己的返回值返回true,因为右孩子包含了1,那么以该节点为root的子树就包含1。

C

代码分析

代码如下:

 public TreeNode pruneTree(TreeNode root) { return pruneTreeHelper(root) ? root : null; }
    // 定义一个helper函数,返回值是该子树是否包含1 public boolean pruneTreeHelper(TreeNode root) { // 空节点返回false if (root == null) { return false; } // 叶节点的话 是1返回true 是0返回false if (root.left == null && root.right == null) { return root.val == 1; }
// 递归调用 boolean left = pruneTreeHelper(root.left); boolean right = pruneTreeHelper(root.right);
// 左孩子不包含1 那么左孩子置空 if (!left) { root.left = null; }
// 右孩子不包含1 那么右孩子置空 if (!right) { root.right = null; }
// 当前节点是否包含1:是左孩子包含1 或者 右孩子包含1 或者 本身就是1 return left || right || root.val == 1; }



如果大家觉得写得不错,不妨关注一下,您的认可是给我最大的鼓励。


以上是关于后序之二叉树裁剪的主要内容,如果未能解决你的问题,请参考以下文章

数据结构实验之二叉树八:(中序后序)求二叉树的深度

《剑指offer》总结三 之二叉树

二叉树篇章之二

❤️算法系列之二叉树的实现(包含前序中序后序遍历以及节点的查找和删除)❤️

数据结构之二叉树

二叉树经典题之二叉树的非递归遍历