Find the closest leaf in a Binary Tree

By | December 24, 2014
Share the joy
  •  
  •  
  •  
  •  
  •  
  •  

Problem description:
Given a Binary Tree and a key ‘k’, find distance of the closest leaf from ‘k’.

              A
            /    \    
           B       C
                 /   \  
                E     F   
               /       \
              G         H
             / \       /
            I   J     K
Closest key to 'H' is 'K', so distance is 1 for 'H'
Closest key to 'C' is 'B', so distance is 2 for 'C'
Closest key to 'E' is either 'I' or 'J', so distance is 2 for 'E' 
Closest key to 'B' is 'B' itself, so distance is 0 for 'B'

Solution:
Find all the ancestry of the target node, and the min-depth of them. Distance from target to its ancestry, plus distance from ancestry to ancestry’s min-depth leaf is a potential result. Among them and the min-depth of the target node itself, find the smallest one.

The traversal process is:
For each node, it traverse the left and right sub-tree, and get the min-depth from each sub-tree. And it will return min-depth to its ancestry.
After traverse each sub-tree, if it found the target in either sub-tree, this node is treated as an ancestry of the target node. And the ancestry information should be stored.

In my code, I define a AncestryInfo class, to restore the ancestry information:
class AncestryInfo{
int[] ancestry_record;    //records the ancestry nodes from target node. Target node is also included in position 0;
int[] ancestry_level;    //records the min deep of ancestry nodes.
int[] leaf;        //records the leaf which the ancestry nodes reach to the min deep
}

  1. public class FindNearestLeaf {
  2.     public static void main(String[] args) {
  3.         Tree tree = Tree.getTree();
  4.         findNearestLeaf(tree, 7);
  5.         System.out.println();
  6.     }
  7.     public static void findNearestLeaf(Tree tree, int value){
  8.         AncestryInfo ancestry = new AncestryInfo();
  9.         //traverse the tree, to find the relative information
  10.         findNearestLeafUtil(tree, value, ancestry, new MyInteger(), new MyInteger(), new MyBoolean());
  11.         int leaf = ancestry.leaf[0];
  12.         int distance = ancestry.ancestry_level[0];
  13.         for(int i=1;i
  14.             if(i-0+ancestry.ancestry_level[i]
  15.                 distance = i-0+ancestry.ancestry_level[i];
  16.                 leaf = ancestry.leaf[i];
  17.             }
  18.         }
  19.         distance–;
  20.         System.out.println(“Nearest Leaf:” + leaf + “\tDistance:” + distance);
  21.     }
  22.     public static void findNearestLeafUtil(Tree root, int value, AncestryInfo anc, MyInteger depth, MyInteger leaf, MyBoolean found){
  23.         if(root==null){
  24.             return;
  25.         }
  26.         MyInteger l_depth = new MyInteger(Integer.MAX_VALUE);
  27.         MyInteger r_depth = new MyInteger(Integer.MAX_VALUE);
  28.         MyBoolean l_found = new MyBoolean();
  29.         MyBoolean r_found = new MyBoolean();
  30.         MyInteger l_leaf = new MyInteger();
  31.         MyInteger r_leaf = new MyInteger();
  32.         if(root.left!=null){
  33.             findNearestLeafUtil(root.left, value, anc, l_depth, l_leaf, l_found);
  34.         }
  35.         if(root.right!=null){
  36.             findNearestLeafUtil(root.right, value, anc, r_depth, r_leaf, r_found);
  37.         }
  38.         if(root.left==null&&root.right==null){    // current node is a leaf
  39.             depth.i = 1;
  40.             leaf.i = root.value;
  41.         }
  42.         else{    //if current node is not a leaf, get the depth from information of 2 sub tress.
  43.             depth.i = Math.min(l_depth.i, r_depth.i) + 1;
  44.             leaf.i = l_depth.i
  45.         }
  46.         found.bool = l_found.bool||r_found.bool;
  47.         if(found.bool){
  48.             //if the target node is already found, then current node is treated as an ancestry. So store the ancestry information.
  49.             anc.ancestry_record = Arrays.copyOf(anc.ancestry_record, anc.ancestry_record.length+1);
  50.             anc.ancestry_record[anc.ancestry_record.length-1] = root.value;
  51.             anc.ancestry_level = Arrays.copyOf(anc.ancestry_level, anc.ancestry_level.length+1);
  52.             anc.ancestry_level[anc.ancestry_level.length-1] = depth.i;
  53.             anc.leaf = Arrays.copyOf(anc.leaf, anc.leaf.length+1);
  54.             anc.leaf[anc.leaf.length-1] = leaf.i;
  55.             return;
  56.         }
  57.         if(root.value==value){    //current node is the target, initial the ancestry information
  58.             found.bool = true;
  59.             anc.ancestry_record = new int[]{root.value};
  60.             anc.ancestry_level = new int[]{depth.i};
  61.             anc.leaf = new int[]{leaf.i};
  62.             return;
  63.         }
  64.         return;
  65.     }
  66. }
  67. class AncestryInfo{
  68.     int[] ancestry_record;    //records the ancestry nodes from target node. Target node is also included in position 0;
  69.     int[] ancestry_level;    //records the min deep of ancestry nodes.
  70.     int[] leaf;        //records the leaf which the ancestry nodes reach to the min deep
  71. }
  72. class MyBoolean {
  73.     public boolean bool;
  74.     public MyBoolean(boolean bool){
  75.         this.bool = bool;
  76.     }
  77.     public MyBoolean(){
  78.         this.bool = false;
  79.     }
  80.     public String toString(){
  81.         return String.valueOf(bool);
  82.     }
  83. }
  84. class MyInteger{
  85.     public int i = 0;
  86.     public MyInteger(int i){
  87.         this.i = i;
  88.     }
  89.     public MyInteger(){}
  90.     public String toString(){
  91.         return String.valueOf(i);
  92.     }
  93. }
  94. class Tree{
  95.     public Tree(int value){
  96.         this.value = value;
  97.     }
  98.     public Tree(String value){
  99.         this.valueString = value;
  100.     }
  101.     public Tree left;
  102.     public Tree right;
  103.     public int value;
  104.     public String valueString;
  105.     public static Tree getTree(){
  106.         Tree t18 = new Tree(18);
  107.         Tree t17 = new Tree(17);
  108.         Tree t16 = new Tree(16);
  109.         Tree t15 = new Tree(15);
  110.         Tree t14 = new Tree(14);
  111.         Tree t13 = new Tree(13);
  112.         Tree t12 = new Tree(12);
  113.         Tree t11 = new Tree(11);
  114.         Tree t10 = new Tree(10);
  115.         Tree t9 = new Tree(9);
  116.         Tree t8 = new Tree(8);
  117.         Tree t7 = new Tree(7);
  118.         Tree t6 = new Tree(6);
  119.         Tree t5 = new Tree(5);
  120.         Tree t4 = new Tree(4);
  121.         Tree t3 = new Tree(3);
  122.         Tree t2 = new Tree(2);
  123.         Tree t1 = new Tree(1);
  124.         t8.left = t9;
  125.         t6.left = t8;
  126.         t5.right = t7;
  127.         t4.left = t5;
  128.         t4.right = t6;
  129.         t2.left = t4;
  130.         t1.left = t2;
  131.         t1.right = t3;
  132.         t6.right = t10;
  133.         t3.left = t11;
  134.         t3.right = t12;
  135.         t12.left = t13;
  136.         t12.right = t14;
  137.         t13.left = t15;
  138.         t13.right = t16;
  139.         t16.right = t17;
  140.         t17.right = t18;
  141.         return t1;
  142.     }
  143. }