将任意二叉树转换为包含 Children Sum 属性的树 – Set 2
问题:给定一棵任意二叉树,将其转换为包含Children Sum Property的二叉树。您只能增加任何节点中的数据值(您不能更改树的结构,也不能减少任何节点的值)。
例如,下面的树不包含孩子的sum 属性,将其转换为包含该属性的树。
50
/ \
/ \
7 2
/ \ /\
/ \ / \
3 5 1 30
朴素方法:本文的第 1 组讨论了朴素方法。在这里,我们正在讨论优化的方法。
算法:将子节点转换为最大可能值,因此在向后移动时,没有父节点的值比子节点更大,因此不会有额外的函数再次遍历该节点的子树。
- 如果子节点的总和小于当前节点,则将两个子节点的值替换为当前节点的值。
if(node->left + node->right < node->data)
put node->data value in both the child
- 如果孩子的总和大于或等于当前节点,则将当前节点的值替换为孩子的总和。
if(node->left->data + node->right->data >= node->data)
put summation of both child data values in node->data
- 在回溯时,用左右子数据之和覆盖现有节点值。
(注意:不会有任何情况下节点的值会大于其子节点的值之和,因为我们已经给了它们可能的最大值)。
请按照以下步骤解决问题:
- 如果root为空,则返回。
- 将变量childSum初始化为0。
- 如果root有孩子,则将它们的值添加到childSum。
- 如果childSum大于等于root->data,则将root->data设置为childSum 。
- 否则,如果有root的孩子,则将其孩子的数据设置为root->data。
- 为root->left和root->right调用相同的函数。
- 将变量totalSumToChangeParent初始化为0 。
- 如果root有孩子,则将其数据的值添加到变量totalSumToChangeParent。
- 如果root 有任何子级,则将 root的值设置为totalSumToChangeParent。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Structure of a node in a binary tree
struct Node {
int data;
Node* left;
Node* right;
Node(int x)
{
data = x;
left = NULL;
right = NULL;
}
};
// Convert the tree such that it holds
// children sum property
void convertTree(Node* root)
{
if (root == NULL)
return;
// Calculating the sum
// of left and right child
int childSum = 0;
if (root->left)
childSum += root->left->data;
if (root->right)
childSum += root->right->data;
// If sum of child is greater
// then change the node's
// data else change the data
// of left and right child to
// make sure they will get
// the maximum possible value
if (childSum >= root->data)
root->data = childSum;
else {
if (root->left)
root->left->data = root->data;
if (root->right)
root->right->data = root->data;
}
// Recursive call for left child
convertTree(root->left);
// Recursive call for right child
convertTree(root->right);
// Overwriting the parent's data
int totalSumToChangeParent = 0;
if (root->left)
totalSumToChangeParent
+= root->left->data;
if (root->right)
totalSumToChangeParent
+= root->right->data;
if (root->left || root->right)
root->data = totalSumToChangeParent;
}
void printInorder(Node* root)
{
if (root == NULL)
return;
// Recursive call to left child
printInorder(root->left);
// Printing the node's data
cout << root->data << " ";
// Recursive call to right child
printInorder(root->right);
}
// Driver Code
int main()
{
Node* root = new Node(50);
root->left = new Node(7);
root->right = new Node(2);
root->left->left = new Node(3);
root->left->right = new Node(5);
root->right->left = new Node(1);
root->right->right = new Node(30);
convertTree(root);
printInorder(root);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Structure of a node in a binary tree
static class Node {
int data;
Node left;
Node right;
Node(int x)
{
data = x;
left = null;
right = null;
}
};
// Convert the tree such that it holds
// children sum property
static void convertTree(Node root)
{
if (root == null)
return;
// Calculating the sum
// of left and right child
int childSum = 0;
if (root.left!=null)
childSum += root.left.data;
if (root.right!=null)
childSum += root.right.data;
// If sum of child is greater
// then change the node's
// data else change the data
// of left and right child to
// make sure they will get
// the maximum possible value
if (childSum >= root.data)
root.data = childSum;
else {
if (root.left!=null)
root.left.data = root.data;
if (root.right!=null)
root.right.data = root.data;
}
// Recursive call for left child
convertTree(root.left);
// Recursive call for right child
convertTree(root.right);
// Overwriting the parent's data
int totalSumToChangeParent = 0;
if (root.left != null)
totalSumToChangeParent
+= root.left.data;
if (root.right != null)
totalSumToChangeParent
+= root.right.data;
if (root.left != null || root.right != null)
root.data = totalSumToChangeParent;
}
static void printInorder(Node root)
{
if (root == null)
return;
// Recursive call to left child
printInorder(root.left);
// Printing the node's data
System.out.print(root.data+ " ");
// Recursive call to right child
printInorder(root.right);
}
// Driver Code
public static void main(String[] args)
{
Node root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);
convertTree(root);
printInorder(root);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code for the above approach
# Class of a node in a binary tree
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Convert the tree such that it holds
# children sum property
def convertTree(root):
if (root == None):
return
# Calculating the sum
# of left and right child
childSum = 0
if (root.left):
childSum += root.left.data
if (root.right):
childSum += root.right.data
# If sum of child is greater
# then change the node's
# data else change the data
# of left and right child to
# make sure they will get
# the maximum possible value
if (childSum >= root.data):
root.data = childSum
else:
if (root.left):
root.left.data = root.data
if (root.right):
root.right.data = root.data
# Recursive call for left child
convertTree(root.left)
# Recursive call for right child
convertTree(root.right)
# Overwriting the parent's data
totalSumToChangeParent = 0
if (root.left):
totalSumToChangeParent += root.left.data
if (root.right):
totalSumToChangeParent += root.right.data
if (root.left or root.right):
root.data = totalSumToChangeParent
def printInorder(root):
if (root == None):
return
# Recursive call to left child
printInorder(root.left)
# Printing the node's data
print(root.data, end=" ")
# Recursive call to right child
printInorder(root.right)
# Driver Code
root = Node(50)
root.left = Node(7)
root.right = Node(2)
root.left.left = Node(3)
root.left.right = Node(5)
root.right.left = Node(1)
root.right.right = Node(30)
convertTree(root)
printInorder(root)
# self code is contributed by Saurabh Jaiswal
C#
// C# program for the above approach
using System;
public class GFG{
// Structure of a node in a binary tree
class Node {
public int data;
public Node left;
public Node right;
public Node(int x)
{
data = x;
left = null;
right = null;
}
};
// Convert the tree such that it holds
// children sum property
static void convertTree(Node root)
{
if (root == null)
return;
// Calculating the sum
// of left and right child
int childSum = 0;
if (root.left!=null)
childSum += root.left.data;
if (root.right!=null)
childSum += root.right.data;
// If sum of child is greater
// then change the node's
// data else change the data
// of left and right child to
// make sure they will get
// the maximum possible value
if (childSum >= root.data)
root.data = childSum;
else {
if (root.left!=null)
root.left.data = root.data;
if (root.right!=null)
root.right.data = root.data;
}
// Recursive call for left child
convertTree(root.left);
// Recursive call for right child
convertTree(root.right);
// Overwriting the parent's data
int totalSumToChangeParent = 0;
if (root.left != null)
totalSumToChangeParent
+= root.left.data;
if (root.right != null)
totalSumToChangeParent
+= root.right.data;
if (root.left != null || root.right != null)
root.data = totalSumToChangeParent;
}
static void printInorder(Node root)
{
if (root == null)
return;
// Recursive call to left child
printInorder(root.left);
// Printing the node's data
Console.Write(root.data+ " ");
// Recursive call to right child
printInorder(root.right);
}
// Driver Code
public static void Main(String[] args)
{
Node root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);
convertTree(root);
printInorder(root);
}
}
// This code is contributed by 29AjayKumar
Javascript
50 100 50 200 50 100 50
时间复杂度: O(N)
辅助空间: O(N)