Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode 222. Count Complete Tree Nodes #76

Open
Woodyiiiiiii opened this issue Jul 17, 2020 · 0 comments
Open

LeetCode 222. Count Complete Tree Nodes #76

Woodyiiiiiii opened this issue Jul 17, 2020 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

Given a complete binary tree, count the number of nodes.

Note:

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 2h nodes inclusive at the last level h.

Example:

Input: 
    1
   / \
  2   3
 / \  /
4  5 6

Output: 6

这道题求的是完全二叉树的节点数。

最简单的方法是直接用先序遍历,遍历所有的节点,这样的时间复杂度是O(n)(n是节点个数),但甚至可以用一行代码来解决:

class Solution {
    int num = 0;
    public int countNodes(TreeNode root) {
        preOrder(root);
        return num;
    }
    void preOrder(TreeNode node) {
        if (node == null) return;
        ++num;
        preOrder(node.left);
        preOrder(node.right);
    }
}

显然上述方法没有利用到完全二叉树的特性,其不可能出现一个只有右孩子而没有左孩子的节点。完全二叉树可以看成是一部分满二叉树加上最后一层叶子节点构成。所以我们可以分两部分求解。先求得二叉树的层数,然后求得满二叉树的节点数是2的层数幂次方减去一(int)Math.pow(2, layerNum - 1) - 1;接着去求最后一层节点数,每层递归,如果当前层数不是最后一层,返回0,否则返回1,最后回溯的结果就是最后一层节点数。这个方法时间复杂度大概是O(l + m),l是树的深度,m是最后一层节点数。

class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) return 0;
        int layerNum = 0;
        TreeNode r = root;
        while (r != null) {
            r = r.left;
            layerNum++;
        }
        if (layerNum == 1) return 1;
        int sum = (int)Math.pow(2, layerNum - 1) - 1;
        sum += getLastLayerNum(root.left, layerNum, 2)
                + getLastLayerNum(root.right, layerNum, 2);
        return sum;
    }
    public int getLastLayerNum(TreeNode root, int layerNum, int nowLayer) {
        if (root == null) {
            return 0;
        }
        if (nowLayer == layerNum) {
            return 1;
        }
        return getLastLayerNum(root.left, layerNum, nowLayer + 1) + 
                getLastLayerNum(root.right, layerNum, nowLayer + 1);
    }
}

还有一种方法同样递归求解,同样每层递归,如果当前层是满二叉树,调用_(1 << height) - 1_,否则继续往下一层。

class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        TreeNode left = root;
        TreeNode right = root;
        int height = 0;
        
        while(right != null) {
            left = left.left;
            right = right.right;
            height++;
        }
        if(left == null) { // Left subtree and right subtree is balanced
            return (1 << height) - 1;  // 2 ^ (height) - 1;
        } else { // Left subtree is deeper than right subtree
            return 1 + countNodes(root.left) + countNodes(root.right);
        }
    }
}

参考资料:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant