📜  最小化二叉树一分为二后形成的子树之和的绝对差

📅  最后修改于: 2022-05-13 01:56:07.947000             🧑  作者: Mango

最小化二叉树一分为二后形成的子树之和的绝对差

给定一棵由N个节点组成的二叉树,任务是通过删除一条边将二叉树分成两个子树,以使子树和的绝对差最小化。

例子:

方法:给定问题可以通过以下步骤解决:

  • 将变量minDiff初始化为 Integer 的最大值,它将存储答案
  • 使用后序遍历将当前节点、左子树和右子树之和存储在当前节点中
  • 使用前序遍历并在每次递归调用时找到子树的总和,如果拆分介于:
    • 当前节点和左子节点
    • 当前节点和右子节点
  • 如果在任何递归调用中子树的差异小于minDiff ,则更新minDiff

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
struct Node {
    Node* left;
    Node* right;
    int val;
  
    Node(int val)
    {
        this->val = val;
        this->left = nullptr;
        this->right = nullptr;
    }
};
 
int postOrder(Node* root)
{
    if (root == nullptr)
        return 0;
    root->val += postOrder(root->left) + postOrder(root->right);
    return root->val;
}
 
void preOrder(Node* root, int minDiff[])
{
    if (root == nullptr)
        return;
 
    // Absolute difference in subtrees
    // if left edge is broken
    int leftDiff = abs(root->left->val - (root->val - root->left->val));
 
    // Absolute difference in subtrees
    // if right edge is broken
    int rightDiff = abs(root->right->val - (root->val - root->right->val));
 
    // Update minDiff if a difference
    // lesser than it is found
    minDiff[0] = min(minDiff[0], min(leftDiff, rightDiff));
 
    return;
}
 
// Function to calculate minimum absolute
// difference of subtrees after
// splitting the tree into two parts
int minAbsDiff(Node* root)
{
 
    // Reference variable
    // to store the answer
    int minDiff[1];
 
    minDiff[0] = INT_MAX;
 
    // Function to store sum of values
    // of current node, left subtree and
    // right subtree in place of
    // current node's value
    postOrder(root);
 
    // Function to perform every
    // possible split and calculate
    // absolute difference of subtrees
    preOrder(root, minDiff);
 
    return minDiff[0];
}
 
int main()
{
    // Construct the tree
    Node* root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(6);
    root->right->right = new Node(7);
 
    // Print the output
    cout << minAbsDiff(root);
 
    return 0;
}
 
// This code is contributed by mukesh07.


Java
// Java implementation for the above approach
import java.lang.Math;
import java.io.*;
 
class GFG {
 
    static class Node {
        Node left, right;
        int val;
        public Node(int val)
        {
            this.val = val;
            this.left = this.right = null;
        }
    }
 
    // Function to calculate minimum absolute
    // difference of subtrees after
    // splitting the tree into two parts
    public static int minAbsDiff(Node root)
    {
 
        // Reference variable
        // to store the answer
        int[] minDiff = new int[1];
 
        minDiff[0] = Integer.MAX_VALUE;
 
        // Function to store sum of values
        // of current node, left subtree and
        // right subtree in place of
        // current node's value
        postOrder(root);
 
        // Function to perform every
        // possible split and calculate
        // absolute difference of subtrees
        preOrder(root, minDiff);
 
        return minDiff[0];
    }
 
    public static int postOrder(Node root)
    {
        if (root == null)
            return 0;
        root.val += postOrder(root.left)
                    + postOrder(root.right);
        return root.val;
    }
 
    public static void preOrder(Node root,
                                int[] minDiff)
    {
        if (root == null)
            return;
 
        // Absolute difference in subtrees
        // if left edge is broken
        int leftDiff
            = Math.abs(root.left.val
                       - (root.val - root.left.val));
 
        // Absolute difference in subtrees
        // if right edge is broken
        int rightDiff
            = Math.abs(root.right.val
                       - (root.val - root.right.val));
 
        // Update minDiff if a difference
        // lesser than it is found
        minDiff[0]
            = Math.min(minDiff[0],
                       Math.min(leftDiff, rightDiff));
 
        return;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        // Construct the tree
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(6);
        root.right.right = new Node(7);
 
        // Print the output
        System.out.println(minAbsDiff(root));
    }
}


Python3
# Python3 implementation for the above approach
import sys
 
# Structure of Node
class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
 
# Function to calculate minimum absolute
# difference of subtrees after
# splitting the tree into two parts
def minAbsDiff(root):
   
    # Reference variable
    # to store the answer
    minDiff = [0]*(1)
 
    minDiff[0] = sys.maxsize
 
    # Function to store sum of values
    # of current node, left subtree and
    # right subtree in place of
    # current node's value
    postOrder(root)
 
    # Function to perform every
    # possible split and calculate
    # absolute difference of subtrees
    preOrder(root, minDiff)
 
    return minDiff[0]
 
def postOrder(root):
    if (root == None):
        return 0
    root.val += postOrder(root.left) + postOrder(root.right)
    return root.val
 
def preOrder(root, minDiff):
    if (root == None):
        return
 
    # Absolute difference in subtrees
    # if left edge is broken
    leftDiff = abs(root.left.val - (root.val - root.left.val))
 
    # Absolute difference in subtrees
    # if right edge is broken
    rightDiff = abs(root.right.val - (root.val - root.right.val))
 
    # Update minDiff if a difference
    # lesser than it is found
    minDiff[0] = min(minDiff[0], min(leftDiff, rightDiff))
 
    return
 
# Construct the tree
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
 
# Print the output
print(minAbsDiff(root))
 
# This code is contributed by rameshtravel07.


C#
// C# implementation for the above approach
using System;
 
public class GFG {
 
    class Node {
        public Node left, right;
        public int val;
    }
 
  static Node newNode(int data)
    {
        Node newNode = new Node();
        newNode.val = data;
        newNode.left= null;
        newNode.right = null;
        return newNode;
    }
 
    // Function to calculate minimum absolute
    // difference of subtrees after
    // splitting the tree into two parts
    static int minAbsDiff(Node root)
    {
 
        // Reference variable
        // to store the answer
        int[] minDiff = new int[1];
 
        minDiff[0] = Int32.MaxValue;
 
        // Function to store sum of values
        // of current node, left subtree and
        // right subtree in place of
        // current node's value
        postOrder(root);
 
        // Function to perform every
        // possible split and calculate
        // absolute difference of subtrees
        preOrder(root, minDiff);
 
        return minDiff[0];
    }
 
   static int postOrder(Node root)
    {
        if (root == null)
            return 0;
        root.val += postOrder(root.left)
                    + postOrder(root.right);
        return root.val;
    }
 
   static void preOrder(Node root,
                                int[] minDiff)
    {
        if (root == null)
            return;
 
        // Absolute difference in subtrees
        // if left edge is broken
        int leftDiff
            = Math.Abs(root.left.val
                       - (root.val - root.left.val));
 
        // Absolute difference in subtrees
        // if right edge is broken
        int rightDiff
            = Math.Abs(root.right.val
                       - (root.val - root.right.val));
 
        // Update minDiff if a difference
        // lesser than it is found
        minDiff[0]
            = Math.Min(minDiff[0],
                       Math.Min(leftDiff, rightDiff));
 
        return;
    }
 
    // Driver code
    public static void Main()
    {
        // Construct the tree
        Node root =  newNode(1);
        root.left =  newNode(2);
        root.right =  newNode(3);
        root.left.left =  newNode(4);
        root.left.right =  newNode(5);
        root.right.left =  newNode(6);
        root.right.right =  newNode(7);
 
        // Print the output
        Console.Write(minAbsDiff(root));
    }
}
 
// This code is contributed by SURENDRA_GANGWAR.


Javascript



输出:
4

时间复杂度:O(N)
辅助空间:O(1)