zoukankan      html  css  js  c++  java
  • [GeeksForGeeks] Check if removing an edge creates two trees of equal size

    Given a Binary Tree, find if there exist edge whose removal creates two trees of equal size.

    Examples:

    Input : root of following tree
               5
             /   
           1      6    
          /      /  
         3      7    4
    Output : true
    Removing edge 5-6 creates two trees of equal size
    
    
    Input : root of following tree
               5
             /   
           1      6    
                /  
               7    4
             /      
            3    2    8
    Output : false
    There is no edge whose removal creates two trees
    of equal size.


    To find whether such an edge exists, we need to find if there is at least one node that meets the following property.

    either this node's left subtree or right subtree has exactly half of the total number of nodes in the given binary tree.

    Solution 1. Top down, O(n^2) runtime

    1.  Count the total number of nodes in given binary tree in O(n) time.

    2.  from top to bottom, check each node to see if it meets the required property. Each check takes O(n) time, so to check

    all nodes, it takes O(n^2) time.

    The bottleneck in this algorithm is the O(n) of checking required property operation. For any node, this algorithm recounts 

    the total number of nodes of its left and right subtree, FROM SCRATCH. For example, for node A and its left child B,

    to check if A meets the property, we need to count how many nodes there are in A's left subtree; 

    to check if B meets the property, we need to count how many nodes there are in B's left/right subtree.

    B's subtree nodes are counted twice already: once for when counting A's left subtree; once for when counting B's subtrees. 

    To avoid this redundant work, we should count bottom up and use memoization to get the number of nodes of given node's subtree in O(1) time.

    This is demonstrated in Solution 2.

     1 public class RemoveEdgeToEqualSize {
     2     public boolean isAnySuchEdgeInefficient(TreeNode root) {
     3         int totalNodes = countTotalNodes(root);        
     4         return checkAllNodes(root, totalNodes);
     5     }
     6     private int countTotalNodes(TreeNode node) {
     7         if(node == null) {
     8             return 0;
     9         }
    10         int count = 1;
    11         count += countTotalNodes(node.left);
    12         count += countTotalNodes(node.right);
    13         return count;
    14     }
    15     private boolean checkOneNode(TreeNode node, int totalNodes) {
    16         if(node == null) {
    17             return false;
    18         }
    19         int leftSubtreeNodes = countTotalNodes(node.left);
    20         if(leftSubtreeNodes * 2 == totalNodes) {
    21             return true;
    22         }
    23         int rightSubtreeNodes = countTotalNodes(node.right);
    24         if(rightSubtreeNodes * 2 == totalNodes) {
    25             return true;
    26         }
    27         return false;
    28     }
    29     private boolean checkAllNodes(TreeNode node, int totalNodes) {
    30         if(node == null) {
    31             return false;
    32         }
    33         if(checkOneNode(node, totalNodes)) {
    34             return true;
    35         }
    36         return checkAllNodes(node.left, totalNodes) || checkAllNodes(node.right, totalNodes);
    37     }
    38 }

    Solution 2. Bottom up, O(n) runtime

    1. Count the total number of nodes in given binary tree in O(n) time.

    2.  From bottom to top,  for each node A, treat it as a root node and count the total number of nodes in this subtree recursively.

    3.  For each node A, check if there exists an edge that halves the given input tree in this subtree of root A. If any of the 3 is true,

    then there exists such an edge in subtree of root A.

      a. subtree of root A has half of all nodes of the given input tree.

      b. there exists such an edge in A's left subtree.

      c.  there exists such an edge in A's right subtree.

    For each node A, it takes O(1) time to calcuate its total number of nodes in subtree of root A. It also takes O(1) time to deterimine

    if there exists such an edge in subtree of root A. So it takes O(n) time to check all nodes in given binary tree.

     1 class ReturnInfo {
     2     int totalCnt;
     3     boolean isAnySuchEdge;
     4     ReturnInfo(int t, boolean b) {
     5         totalCnt = t;
     6         isAnySuchEdge = b;
     7     }
     8 }
     9 public class RemoveEdgeToEqualSize {
    10     public boolean isAnySuchEdgeEfficient(TreeNode root) {
    11         int totalNodes = countTotalNodes(root);
    12         return recurHelper(root, totalNodes).isAnySuchEdge;
    13     }
    14     private ReturnInfo recurHelper(TreeNode node, int totalNodes) {
    15         ReturnInfo ret = new ReturnInfo(0, false);
    16         if(node == null) {
    17             return ret;
    18         }
    19         ReturnInfo left = recurHelper(node.left, totalNodes);
    20         ReturnInfo right = recurHelper(node.right, totalNodes);
    21         ret.totalCnt = 1 + left.totalCnt + right.totalCnt;
    22         ret.isAnySuchEdge = ret.totalCnt * 2 == totalNodes || left.isAnySuchEdge || right.isAnySuchEdge;
    23         return ret;
    24     }
    25 }


  • 相关阅读:
    cocos2d-x C++的do...while(0)另类使用方法
    C++ Virtual详解
    xcode5向APP store上传应用的时候注意点
    IOS7学习之路九(ios7自定义UIAlertView)
    IOS7学习之路八(iOS 禁止屏幕旋转的方法)
    Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to XXX-------动态代理(proxy-target-class属性的意义)
    Maven支持第三方库大全
    EOS page问题
    EOS页面流参数传值问题
    XML中转义字符及使用
  • 原文地址:https://www.cnblogs.com/lz87/p/7508149.html
Copyright © 2011-2022 走看看