Message on Whatsapp 8879355057 for DSA(OA + Interview) + Fullstack Dev Training + 1-1 Personalized Mentoring to get 10+LPA Job
0 like 0 dislike
657 views
in Online Assessments by Expert (46,090 points) | 657 views

2 Answers

0 like 0 dislike
Best answer

Given a complete binary tree, you need find a node at which the next node need to be inserted, in the least time complexity.
Each node in binary tree is contains left, right and value only.

 

             5
           /.  \
          4      8
         / 
        3   

 

the next node is going to be insert in right side of 4.

 

I've given a solution that takes O(n) time [ BFS- Level order traversal ] with O(n) space complexity.

 

But he is insting me to done in O(logn) time.

 

Obeservation:
In complete binary tree, the node either added after the last level [when its full BT] or at the last level[when its not full BT].

 

We can find the height of binary tree in O(logn) time, hence the level.

 

We need to somehow discard half of the tree in processing everytime in order to get O(logn)

by Expert (46,090 points)
0 like 0 dislike

Solution in O(log(n)^2)

 

 /**
     * O(log(n)^2)
     *
     * @param root
     * @return
     */
    public TreeNode getLastNodeInCompleteBinaryTree(TreeNode root) {

        /**
         * if root is null, then add at root it self
         * O(1)
         */
        if (null == root)
            return root;


        /**
         * if root don't have left child, then add at left side
         * O(1)
         */
        if (root.left == null)
            return root;

        /**
         * if root don't have right child but has left child, then add at right side
         *
         * O(1)
         */
        if (root.right == null)
            return root;


        /**
         * check does tree rooted at this node has left and right height same.
         * If yes, then it will only possible when this tree is full binary tree.
         * Then we can simply add a node at the left side of leftmost node
         */

        if (leftRightHeightAreSame(root)) { //O(log(n))

            return getLeftMostNode(root); //O(log(n))

        } else if (leftRightHeightAreSame(root.left)) { //O(log(n))
            /**
             * if left and right are not same but its true for left sub-tree
             * i.e. left is full binary tree [keep in mind we talk about the complete binary as input]
             * we need to add at right sub-tree
             */
            return getLastNodeInCompleteBinaryTree(root.right);  //O(log(n))
        } else
            return getLastNodeInCompleteBinaryTree(root.left); //O(log(n))

    }

    /**
     * O(log(n))
     *
     * @param root
     * @return
     */
    private boolean leftRightHeightAreSame(TreeNode root) {
        if (root == null)
            return true;

        if (root.left == null && root.right == null)
            return true;

        return leftHeight(root) == rightHeight(root);
    }


    /**
     * O(log(n))
     *
     * @param root
     * @return
     */
    private int leftHeight(TreeNode root) {
        if (root == null)
            return 0;
        return 1 + leftHeight(root.left);
    }

    /**
     * O(log(n))
     *
     * @param root
     * @return
     */
    private int rightHeight(TreeNode root) {
        if (root == null)
            return 0;
        return 1 + rightHeight(root.right);
    }

    /**
     * O(log(n))
     *
     * @param root
     * @return
     */
    private TreeNode getLeftMostNode(TreeNode root) {

        while (root != null && root.left != null)
            root = root.left;

        return root;

    }

 

Driver

 

public static void main(String[] args) {

        LastNodeInCompleteBinaryTree binaryTree = new LastNodeInCompleteBinaryTree();
        /**
         * *     1
         * *    / \
         * *   2   3
         * *  / \  /
         * * 4  5 6
         *
         * @return
         */
        System.out.println(binaryTree.getLastNodeInCompleteBinaryTree(Helper.getTree1()));

        /**
         * *     1
         * *    / \
         * *   2   3
         * *  / \  /\
         * * 4  5 6 7
         *
         * @return
         */
        System.out.println(binaryTree.getLastNodeInCompleteBinaryTree(Helper.getTree2()));


        /**
         * *           1
         * *          /  \
         * *         2    3
         * *         / \  /\
         * *        4  5 6 7
         * *      /  \
         * *     8    9
         *
         * @return
         */
        System.out.println(binaryTree.getLastNodeInCompleteBinaryTree(Helper.getTree3()));


        /**
         * *           1
         * *          /  \
         * *         2    3
         * *        /    /
         * *       4    6
         *
         * @return
         */
        System.out.println(binaryTree.getLastNodeInCompleteBinaryTree(Helper.notCompleteBinaryTree()));
    }
	

 

Output

 

TreeNode{val=3, left=TreeNode{val=6, left=null, right=null}, right=null}
TreeNode{val=4, left=null, right=null}
TreeNode{val=5, left=null, right=null}
TreeNode{val=2, left=TreeNode{val=4, left=null, right=null}, right=null}

 

 

by Expert (46,090 points)