精品推荐:
在牛客网上看到一网友发出自己近几年在华为的薪资待遇,3年的时间从刚入职的月薪18000到全年56万,升的确实挺快,该网友感慨:华为这个薪资不愧是一线大厂守门员。
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第814题:二叉树剪枝。
问题描述
来源:LeetCode第814题
难度:中等
给你二叉树的根结点 root ,此外树的每个结点的值要么是 0 ,要么是 1 。返回移除了所有不包含 1 的子树的原二叉树。节点 node 的子树为 node 本身加上所有 node 的后代。
示例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]
树中节点的数目在范围 [1, 200] 内
Node.val 为 0 或 1
问题分析
这题说的是删除二叉树中不含 1 的子树,如果从上到下判断所有的子树是否包含 1 ,这个效率比较低。
我们可以考虑从下往上的方式来操作二叉树,如果一个节点是叶子节点并且值是 0 ,我们就把它删除。
注意这里的非叶子节点并不是固定的,因为如果一个节点的子树都是 0 ,我们把它的子树删除之后,它就变成叶子节点了。
JAVA:
// 从下往上操作二叉树,参考二叉树的后序遍历
public TreeNode pruneTree(TreeNode root) {
if (root == null)
return null;
// 当前节点可能不是叶子节点,但如果他的子节点
// 都删除完了,它就变成了叶子节点。
root.left = pruneTree(root.left);// 剪枝左子树
root.right = pruneTree(root.right);// 剪枝右子树
// 如果叶子节点的值是0,就把他给删除,返回一个空的节点
if (root.left == null && root.right == null && root.val == 0)
return null;
return root;// 否则不要删除,直接返回
}
C++:
// 从下往上操作二叉树,参考二叉树的后序遍历
public:
TreeNode *pruneTree(TreeNode *root) {
if (!root)
return nullptr;
// 当前节点可能不是叶子节点,但如果他的子节点
// 都删除完了,它就变成了叶子节点。
root->left = pruneTree(root->left);// 剪枝左子树
root->right = pruneTree(root->right);// 剪枝右子树
// 如果叶子节点的值是0,就把他给删除,返回一个空的节点
if (!root->left && !root->right && !root->val)
return nullptr;
return root;// 否则不要删除,直接返回
}
Python:
# 从下往上操作二叉树,参考二叉树的后序遍历
def pruneTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
# 当前节点可能不是叶子节点,但如果他的子节点
# 都删除完了,它就变成了叶子节点。
root.left = self.pruneTree(root.left) # 剪枝左子树
root.right = self.pruneTree(root.right) # 剪枝右子树
# 如果叶子节点的值是0,就把他给删除,返回一个空的节点
if not root.left and not root.right and root.val == 0:
return None
return root # 否则不要删除,直接返回
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。