持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题目链接:814. 二叉树剪枝
题目描述
给你二叉树的根结点 root ,此外树的每个结点的值要么是 0 ,要么是 1 。
返回移除了所有不包含 1 的子树的原二叉树。
节点 node 的子树为 node 本身加上所有 node 的后代。
提示:
- 树中节点的数目在范围
[1, 200]内 Node.val为0或1
示例 1:
输入:root = [1,null,0,0,1]
输出:[1,null,0,null,1]
解释:
只有红色节点满足条件“所有不包含 1 的子树”。 右图为返回的答案。
示例 2:
输入: root = [1,0,1,0,0,0,1]
输出: [1,null,1,null,1]
示例 3:
输入: root = [1,1,0,1,1,0,1,0]
输出: [1,1,0,1,1,null,1]
整理题意
题目给定一颗二叉树,二叉树中每个节点的值要么是 0,要么是 1。要求删除不包含节点值为 1 的子树。也就是如果当前节点值为 0,且它的左子树和右子树中不包含节点值为 1 的节点,那么就删除以当前节点为根的子树。
解题思路分析
该题涉及二叉树且可以转化为子问题,所以我们可以使用递归的思想来解决。
判断当前节点值以及当前节点的左子树和右子树是否包含节点值为 1 的节点即可。
具体实现
- 首先处理边界情况,当输入为空时,即可返回空指针即可。
- 对左子树和右子树分别进行递归处理。
- 如果左子树和右子树同时为空的情况下并且当前节点值为
0,表示当前节点的左子树和右子树都不包含值为1的节点,并且自身的值也不为1,那么满足题目删除当前节点的条件,此时返回空指针。 - 否则表示以当前节点为根节点的子树包含值为
1的节点,无需删除当前节点,直接返回当前节点。
复杂度分析
- 时间复杂度:,其中
n是二叉树节点的个数。每个节点都需要遍历一次。 - 空间复杂度:,其中
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的个数。 - 测试结果:
结束语
岁月是有痕的,未来是由现在创造的。你看过的书、经历的事、走过的地方、做出的努力,都会悄悄影响你、改变你。请珍惜每一个机会,认真对待每一件事,见证一个不断成长的自己。新的一天,加油!