给定一棵完整的二叉树,其N层编号为[0, (N – 1 )],从根到最低层按降序排列,权重在[1, 2 N – 1]之间编号,从根到最后一个叶节点递增顺序,每个节点的任务是根据以下条件调整其左右子树中存在的所有节点的级别值:
- 通过权重的差异增加较轻子树的所有节点的级别。
- 通过权重的差异降低较重子树的所有节点的级别。
例子:
Input:
Output: 0 0 -2
Explanation:
The initial levels of the nodes {1,2,3} are {0,-1,-1} respectively.
The root node remains unchanged.
The weight of left subtree is 2 and the weight of the right subtree is 3.
So, the left subtree goes up by (3 – 2) = 1 level to 0.
The right subtree goes down by 1 level to -2.
Input:
Output: 0 4 -6 4 2 -6 -8
Explanation:
The initial levels of the nodes {1,2,3,4,5,6,7} are {0,-1,-1,-2,-2,-2,-2} respectively.
The root node remains unchanged.
The weight of the left subtree {2,4,5} is 11.
The weight of the right subtree {3,6,7} is 16.
Hence, all the nodes in left subtree move up by 5 while those in the right subtree moves down by 5.
Thus, the new levels of every node are:
Node 2: -1 + 5 = 4
Node 3: -1 – 5 = -6
Node 4,5: -2 + 5 = 3
Node 6,7: -2 – 5 = -7
Now, nodes 4,5 further based on the difference of their weights (5 -4 ) = 1.
Node 4: 3 + 1 = 4
Node 5: 3 – 1 = 2
Similarly, nodes 6,7 also get adjusted.
Node 6: -7 + 1 = -6
Node 7: -7 – 1 = -8
Hence, the final adjusted levels of all the nodes are 0 4 -6 4 2 -6 -8.
方法:为了解决这个问题,我们计算每个节点的左(w_left)和右(w_right)子树的权重并存储它们的差值K 。计算后,我们递归地将其较轻子树的所有节点的级别值增加K,并将其较重子树的级别从各自的当前值减少K。计算完所有节点后,我们将显示每个节点的级别的最终值。
下面的代码是上述方法的实现:
C++
1
/ \
2 3
Java
1
/ \
2 3
/ \ / \
4 5 6 7
Python3
// C++ Program to print updated levels
// of each node of a Complete Binary Tree
// based on difference in weights of subtrees
#include
using namespace std;
// Node for the given binary tree
struct node {
int weight;
// stores the weight of node
int level;
// stores the level of node
struct node* left;
struct node* right;
node(int w, int l)
{
this->weight = w;
this->level = l;
left = right = NULL;
}
};
// Utility function to insert a node
// in a tree rooted at root
struct node* insert(struct node* root,
int n_weight,
int n_level, queue& q)
{
struct node* n
= new node(n_weight, n_level);
// if the tree is empty till now
// make node n the root
if (root == NULL)
root = n;
// If the frontmost node of
// queue has no left child
// make node n its left child
// the frontmost node still
// remains in the queue because
// its right child is null yet
else if (q.front()->left == NULL) {
q.front()->left = n;
}
// Make node n the right child of
// the frontmost node and remove
// the front node from queue
else {
q.front()->right = n;
q.pop();
}
// push the node n into queue
q.push(n);
return root;
}
// Function to create a complete binary tree
struct node* createTree(vector weights,
vector levels)
{
// initialise the root node of tree
struct node* root = NULL;
// initialise a queue of nodes
queue q;
int n = weights.size();
for (int i = 0; i < n; i++) {
/*
keep inserting nodes with weight values
from the weights vector and level values
from the levels vector
*/
root = insert(root, weights[i],
levels[i], q);
}
return root;
}
// Function to print final levels of nodes
void printNodeLevels(struct node* root)
{
if (root == NULL)
return;
queue q;
q.push(root);
while (!q.empty()) {
cout << q.front()->level << " ";
if (q.front()->left != NULL)
q.push(q.front()->left);
if (q.front()->right != NULL)
q.push(q.front()->right);
q.pop();
}
cout << endl;
}
// Function to find the weight of subtree
int findWeight(struct node* root)
{
// If the root node is null
// then weight of subtree will be 0
if (root == NULL)
return 0;
return root->weight +
findWeight(root->left)
+ findWeight(root->right);
}
// Function to compute new level
// of the nodes based on the
// difference of weight K
void changeLevels(struct node* root, int k)
{
if (root == NULL)
return;
// Change the level of root node
root->level = root->level + k;
// Recursively change the level of
// left and right subtree
changeLevels(root->left, k);
changeLevels(root->right, k);
}
// Function to calculate weight of
// the left and the right subtrees and
// adjust levels based on their difference
void adjustLevels(struct node* root)
{
// No adjustment required
// when root is null
if (root == NULL)
return;
// Find weights of left
// and right subtrees
int w_left = findWeight(root->left);
int w_right = findWeight(root->right);
// find the difference between the
// weights of left and right subtree
int w_diff = w_left - w_right;
// Change the levels of nodes
// according to weight difference at root
changeLevels(root->left, -w_diff);
changeLevels(root->right, w_diff);
// Recursively adjust the levels
// for left and right subtrees
adjustLevels(root->left);
adjustLevels(root->right);
}
// Driver code
int main()
{
// Number of levels
int N = 3;
// Number of nodes
int nodes = pow(2, N) - 1;
vector weights;
// Vector to store weights of tree nodes
for (int i = 1; i <= nodes; i++) {
weights.push_back(i);
}
vector levels;
// Vector to store levels of every nodes
for (int i = 0; i < N; i++) {
// 2^i nodes are present at ith level
for (int j = 0; j < pow(2, i); j++) {
// value of level becomes negative
// while going down the root
levels.push_back(-1 * i);
}
}
// Create tree with the
// given weights and levels
struct node* root
= createTree(weights, levels);
// Adjust the levels
adjustLevels(root);
// Display the final levels
printNodeLevels(root);
return 0;
}
// Java Program to print updated levels
// of each node of a Complete Binary Tree
// based on difference in weights of subtrees
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class GFG {
// Node for the given binary tree
static class node {
int weight;
// stores the weight of node
int level;
// stores the level of node
node left;
node right;
public node(int w, int l)
{
this.weight = w;
this.level = l;
left = right = null;
}
}
// Utility function to insert a node
// in a tree rooted at root
static node insert(node root, int n_weight, int n_level, Queue q)
{
node n = new node(n_weight, n_level);
// if the tree is empty till now
// make node n the root
if (root == null)
root = n;
// If the frontmost node of
// queue has no left child
// make node n its left child
// the frontmost node still
// remains in the queue because
// its right child isnull yet
else if (q.peek().left == null)
{
q.peek().left = n;
}
// Make node n the right child of
// the frontmost node and remove
// the front node from queue
else
{
q.peek().right = n;
q.poll();
}
// push the node n into queue
q.add(n);
return root;
}
// Function to create a complete binary tree
static node createTree(ArrayList weights,
ArrayList levels)
{
// initialise the root node of tree
node root = null;
// initialise a queue of nodes
Queue q = new LinkedList<>();
int n = weights.size();
for (int i = 0; i < n; i++)
{
/*
* keep inserting nodes with weight values
* from the weights vector and level
* values from the levels vector
*/
root = insert(root, weights.get(i), levels.get(i), q);
}
return root;
}
// Function to print final levels of nodes
static void printNodeLevels(node root)
{
if (root == null)
return;
Queue q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
System.out.print(q.peek().level + " ");
if (q.peek().left != null)
q.add(q.peek().left);
if (q.peek().right != null)
q.add(q.peek().right);
q.poll();
}
System.out.println();
}
// Function to find the weight of subtree
static int findWeight(node root)
{
// If the root node isnull
// then weight of subtree will be 0
if (root == null)
return 0;
return root.weight + findWeight(root.left) + findWeight(root.right);
}
// Function to compute new level
// of the nodes based on the
// difference of weight K
static void changeLevels(node root, int k)
{
if (root == null)
return;
// Change the level of root node
root.level = root.level + k;
// Recursively change the level of
// left and right subtree
changeLevels(root.left, k);
changeLevels(root.right, k);
}
// Function to calculate weight of
// the left and the right subtrees and
// adjust levels based on their difference
static void adjustLevels(node root)
{
// No adjustment required
// when root isnull
if (root == null)
return;
// Find weights of left
// and right subtrees
int w_left = findWeight(root.left);
int w_right = findWeight(root.right);
// find the difference between the
// weights of left and right subtree
int w_diff = w_left - w_right;
// Change the levels of nodes
// according to weight difference at root
changeLevels(root.left, -w_diff);
changeLevels(root.right, w_diff);
// Recursively adjust the levels
// for left and right subtrees
adjustLevels(root.left);
adjustLevels(root.right);
}
// Driver code
public static void main(String[] args)
{
// Number of levels
int N = 3;
// Number of nodes
int nodes = (int) Math.pow(2, N) - 1;
// Vector to store weights of tree nodes
ArrayList weights = new ArrayList<>();
for (int i = 1; i <= nodes; i++) {
weights.add(i);
}
// Vector to store levels of every nodes
ArrayList levels = new ArrayList<>();
for (int i = 0; i < N; i++) {
// 2^i nodes are present at ith level
for (int j = 0; j < (int) Math.pow(2, i); j++) {
// value of level becomes negative
// while going down the root
levels.add(-1 * i);
}
}
// Create tree with the
// given weights and levels
node root = createTree(weights, levels);
// Adjust the levels
adjustLevels(root);
// Display the final levels
printNodeLevels(root);
}
}
// This code is contributed by sanjeev2552
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live