修剪给定二叉树的任何仅包含 0 的子树
给定一棵二叉树,任务是为任何仅包含 0 的子树修剪这棵树。
例子:
Input:
1
\
0
/ \
0 1
Output:
1
\
0
\
1
Explanation:
The subtree shown as bold below
does not contain any 1.
Hence it can be trimmed.
1
\
0
/ \
0 1
Input:
1
/ \
1 0
/ \ / \
1 1 0 1
/
0
Output:
1
/ \
1 0
/ \ \
1 1 1
Input:
1
/ \
0 1
/ \ / \
0 0 0 1
Output:
1
\
1
\
1
方法:给定的问题可以使用后序遍历来解决。这个想法是如果左右子树都为空并且当前节点的值为0,则将空节点返回给父节点。这将删除甚至不包含单个1的子树。按照以下步骤解决问题:
- 如果根为 null,我们只需返回 null。
- 在左右子树上递归调用函数
- 如果左子树和右子树返回 null 并且当前节点的值为 0 返回 null
- 否则返回当前节点本身
下面是上述方法的实现:
C++
// C++ program for above approach
#include
using namespace std;
class TreeNode {
public:
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int val)
{
data = val;
left = NULL;
right = NULL;
}
};
// Inorder function to print the tree
void inorderPrint(TreeNode* root)
{
if (root == NULL)
return;
inorderPrint(root->left);
cout << root->data << " ";
inorderPrint(root->right);
}
// Postorder traversal
TreeNode* TrimTree(TreeNode* root)
{
if (!root)
return nullptr;
// Traverse from leaf to node
root->left = TrimTree(root->left);
root->right = TrimTree(root->right);
// We only trim if the node's value is 0
// and children are null
if (root->data == 0 && root->left == nullptr
&& root->right == nullptr) {
// We trim the subtree by returning nullptr
return nullptr;
}
// Otherwise we leave the node the way it is
return root;
}
// Driver code
int main()
{
/*
1
/ \
0 1
/ \ / \
0 0 0 1
*/
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(0);
root->right = new TreeNode(1);
root->left->left = new TreeNode(0);
root->left->right = new TreeNode(0);
root->right->left = new TreeNode(0);
root->right->right = new TreeNode(1);
TreeNode* ReceivedRoot = TrimTree(root);
cout << endl;
inorderPrint(ReceivedRoot);
/*
1
\
1
\
1
*/
}
Java
// Java program for above approach
class GFG{
static class TreeNode {
int data;
TreeNode left;
TreeNode right;
TreeNode(int val)
{
data = val;
left = null;
right = null;
}
};
// Inorder function to print the tree
static void inorderPrint(TreeNode root)
{
if (root == null)
return;
inorderPrint(root.left);
System.out.print(root.data+ " ");
inorderPrint(root.right);
}
// Postorder traversal
static TreeNode TrimTree(TreeNode root)
{
if (root==null)
return null;
// Traverse from leaf to node
root.left = TrimTree(root.left);
root.right = TrimTree(root.right);
// We only trim if the node's value is 0
// and children are null
if (root.data == 0 && root.left == null
&& root.right == null) {
// We trim the subtree by returning null
return null;
}
// Otherwise we leave the node the way it is
return root;
}
// Driver code
public static void main(String[] args)
{
/*
1
/ \
0 1
/ \ / \
0 0 0 1
*/
TreeNode root = new TreeNode(1);
root.left = new TreeNode(0);
root.right = new TreeNode(1);
root.left.left = new TreeNode(0);
root.left.right = new TreeNode(0);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(1);
TreeNode ReceivedRoot = TrimTree(root);
System.out.println();
inorderPrint(ReceivedRoot);
/*
1
\
1
\
1
*/
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program for above approach
class TreeNode:
def __init__(self, data):
self.data = data # Assign data
self.left = None
self.right = None;
# Inorder function to print the tree
def inorderPrint(root):
if (root == None):
return;
inorderPrint(root.left);
print(root.data, end = " ");
inorderPrint(root.right);
# Postorder traversal
def TrimTree(root):
if (root == None):
return None;
# Traverse from leaf to Node
root.left = TrimTree(root.left);
root.right = TrimTree(root.right);
# We only trim if the Node's value is 0
# and children are None
if (root.data == 0 and root.left == None and root.right == None):
# We trim the subtree by returning None
return None;
# Otherwise we leave the Node the way it is
return root;
# Driver code
if __name__ == '__main__':
'''
1
/ \
0 1
/ \ / \
0 0 0 1
'''
root = TreeNode(1);
root.left = TreeNode(0);
root.right = TreeNode(1);
root.left.left = TreeNode(0);
root.left.right = TreeNode(0);
root.right.left = TreeNode(0);
root.right.right = TreeNode(1);
ReceivedRoot = TrimTree(root);
print();
inorderPrint(ReceivedRoot);
'''
1
\
1
\
1
'''
# This code is contributed by shikhasingrajput
C#
// C# program for above approach
using System;
public class GFG{
class TreeNode {
public int data;
public TreeNode left;
public TreeNode right;
public TreeNode(int val)
{
data = val;
left = null;
right = null;
}
};
// Inorder function to print the tree
static void inorderPrint(TreeNode root)
{
if (root == null)
return;
inorderPrint(root.left);
Console.Write(root.data+ " ");
inorderPrint(root.right);
}
// Postorder traversal
static TreeNode TrimTree(TreeNode root)
{
if (root==null)
return null;
// Traverse from leaf to node
root.left = TrimTree(root.left);
root.right = TrimTree(root.right);
// We only trim if the node's value is 0
// and children are null
if (root.data == 0 && root.left == null
&& root.right == null) {
// We trim the subtree by returning null
return null;
}
// Otherwise we leave the node the way it is
return root;
}
// Driver code
public static void Main(String[] args)
{
/*
1
/ \
0 1
/ \ / \
0 0 0 1
*/
TreeNode root = new TreeNode(1);
root.left = new TreeNode(0);
root.right = new TreeNode(1);
root.left.left = new TreeNode(0);
root.left.right = new TreeNode(0);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(1);
TreeNode ReceivedRoot = TrimTree(root);
Console.WriteLine();
inorderPrint(ReceivedRoot);
/*
1
\
1
\
1
*/
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
1 1 1
时间复杂度: O(N),其中 N 是树中的节点数。
辅助空间: O(H),递归调用栈可以和树的高度H一样大。在最坏的情况下,当树倾斜时,H = N。