222 Count Complete Tree Nodes

Given a complete binary tree, count the number of nodes.
Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and $$2^h$$ nodes inclusive at the last level $$h$$.

Solution:
iterative-V1 (328 ms)

class Solution {
public:
    int left_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->left;
            i += 1;
        }
        return i;
    }
    int right_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->right;
            i += 1;
        }
        return i;
    }
    int countNodes(TreeNode* root) {
        if ( root == NULL ) return 0;
        int res = 0;
        while ( root != NULL ) {
            int ll = left_height(root->left), lr = right_height(root->left);
            int rl = left_height(root->right), rr = right_height(root->right);
            if ( ll == rr ) return res + pow(2, ll+1) - 1;
            if ( ll == rl ) {
                res += pow(2, ll);
                root = root->right;
                continue;
            }
            if ( ll == lr ) return res + pow(2, ll) + pow(2, rr) - 1;
            res += pow(2, rr);
            root = root->left;
        }
        return res;
    }
};

iterative-V2 (280 ms)

class Solution {
public:
    int left_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->left;
            i += 1;
        }
        return i;
    }
    int right_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->right;
            i += 1;
        }
        return i;
    }
    int countNodes(TreeNode* root) {
        if ( root == NULL ) return 0;
        int res = 0;
        int ll = 0, lr = 0, rl = 0, rr = 0;
        while ( root != NULL ) {
            if ( ll == 0 ) ll = left_height(root->left);
            if ( lr == 0 ) lr = right_height(root->left);
            if ( rl == 0 ) rl = left_height(root->right);
            if ( rr == 0 ) rr = right_height(root->right);
            if ( ll == rr ) return res + pow(2, ll+1) - 1;
            if ( ll == rl ) {
                res += pow(2, ll);
                root = root->right;
                ll = rl-1;
                rr = rr-1;
                rl = 0;
                lr = 0;
                continue;
            }
            if ( ll == lr ) return res + pow(2, ll) + pow(2, rr) - 1;
            res += pow(2, rr);
            root = root->left;
            ll = ll - 1;
            rr = lr - 1;
            lr = 0;
            rl = 0;
        }
        return res;
    }
};

iterative-V3 (80 ms)

class Solution {
    public: 
    int countNodes(TreeNode* root) { 
        int count = 0;
        int l_lh = 0, r_lh = 0;
        TreeNode *tnode;

        while (root != NULL ){
            if ( l_lh == 0 ) {
                tnode = root->left;
                while ( tnode != NULL ) {l_lh += 1;tnode = tnode->left;}
            }
            if ( r_lh == 0 ) {
                tnode = root->right;
                while ( tnode != NULL ) {r_lh += 1;tnode = tnode->left;}
            }
            if ( l_lh == r_lh ) {
                count += 1<<l_lh;
                root = root->right;
                l_lh = r_lh - 1;
                r_lh = 0;
            }
            else {
                count += 1<<r_lh;
                root = root->left;
                l_lh = l_lh -1;
                r_lh = 0;
            }
        }
        return count;
    }
};

Recursive

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int left_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->left;
            i += 1;
        }
        return i;
    }
    int right_height(TreeNode* root) {
        int i = 0;
        while ( root != NULL ) {
            root = root->right;
            i += 1;
        }
        return i;
    }
    int countNodes(TreeNode* root) {
        if ( root == NULL ) return 0;
        int ll = left_height(root->left), lr = right_height(root->left);
        int rl = left_height(root->right), rr = right_height(root->right);
        if ( ll == rr ) return pow(2, ll+1) - 1;
        if ( ll == rl ) return pow(2, ll) + countNodes(root->right);
        if ( ll == lr ) return pow(2, ll) + pow(2, rr) - 1;
        return pow(2, rr) + countNodes(root->left);
    }
};

Notes Record four heights: ll, lr, rl, rr.
The following relation always hold:

$$ll \leq lr \leq rl \leq rr$$ and $$rr - ll \leq 1$$.

Consider following four situation:

  • n, n, n, n:
    number of nodes = $$2^{(n+1)}-1$$
  • n, n, n, n-1:
    number of nodes = $$2^n$$ + countNodes(root->right)
  • n, n, n-1, n-1:
    number of nodes = $$2^n + 2^{n-1}-1$$
  • n, n-1, n-1, n-1:
    number of nodes = countNodes(root->left) + $$2^{n-1}$$

Actually we only have to consider two heights: ll and lr. Consider two following situation:

  • $$ll = lr$$:
    Left sub-tree is full, number of nodes = $$2^{ll}$$ + countNodes(root->right);
  • $$ll=lr+1$$: Right sub-tree is full, number of nodes = $$2^{lr}$$ + countNodes(root->left);

results matching ""

    No results matching ""