【C/C++】814. 二叉树剪枝

201 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情


题目链接:814. 二叉树剪枝

题目描述

给你二叉树的根结点 root ,此外树的每个结点的值要么是 0 ,要么是 1

返回移除了所有不包含 1 的子树的原二叉树。

节点 node 的子树为 node 本身加上所有 node 的后代。

提示:

  • 树中节点的数目在范围 [1, 200] 内
  • Node.val 为 0 或 1

示例 1:

1028_2.png

输入:root = [1,null,0,0,1]
输出:[1,null,0,null,1]
解释:
只有红色节点满足条件“所有不包含 1 的子树”。 右图为返回的答案。

示例 2:

1028_1.png

输入: root = [1,0,1,0,0,0,1]
输出: [1,null,1,null,1]

示例 3:

1028.png

输入: root = [1,1,0,1,1,0,1,0]
输出: [1,1,0,1,1,null,1]

整理题意

题目给定一颗二叉树,二叉树中每个节点的值要么是 0,要么是 1。要求删除不包含节点值为 1 的子树。也就是如果当前节点值为 0,且它的左子树和右子树中不包含节点值为 1 的节点,那么就删除以当前节点为根的子树。

解题思路分析

该题涉及二叉树且可以转化为子问题,所以我们可以使用递归的思想来解决。

判断当前节点值以及当前节点的左子树和右子树是否包含节点值为 1 的节点即可。

具体实现

  1. 首先处理边界情况,当输入为空时,即可返回空指针即可。
  2. 对左子树和右子树分别进行递归处理。
  3. 如果左子树和右子树同时为空的情况下并且当前节点值为 0,表示当前节点的左子树和右子树都不包含值为 1 的节点,并且自身的值也不为 1,那么满足题目删除当前节点的条件,此时返回空指针。
  4. 否则表示以当前节点为根节点的子树包含值为 1 的节点,无需删除当前节点,直接返回当前节点。

复杂度分析

  • 时间复杂度:O(n)O(n),其中 n 是二叉树节点的个数。每个节点都需要遍历一次。
  • 空间复杂度:O(n)O(n),其中 n 是二叉树节点的个数。递归的深度最多为 O(n)O(n)

代码实现

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
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) return nullptr;
        return root;
    }
};

总结

  • 该题巧妙的使用递归的方法进行解题,隐性的处理了子树不包含节点值为 1 的情况。
  • 核心思路为 统计子树中节点值为 1 的个数
  • 测试结果:

814.png

结束语

岁月是有痕的,未来是由现在创造的。你看过的书、经历的事、走过的地方、做出的努力,都会悄悄影响你、改变你。请珍惜每一个机会,认真对待每一件事,见证一个不断成长的自己。新的一天,加油!