题目链接:LeetCode222展开目录
题解展开目录
常规思路,遍历整棵树,时间复杂度 O (N),但是有一种时间复杂度小于 O (N) 的做法
首先遍历头结点右子树的最左边界,如果最左边界不为空,说明头结点的左子树是满二叉树,利用满二叉树的性质,结点个数就为 $2^h-1$,再加上头结点,所以结果就是 $2^h$,这个时间复杂度是 O (logN) 的,然后再递归遍历右子树求出有多少结点即可
如果最左边界为空,说明头结点的右子树是一棵高度为 $h-1$ 的满二叉树,那么右子树加上头结点的总结点个数就为 $2^{h-1}$,然后再递归遍历头节点的左子树即可
代码展开目录
- class Solution {
- int h;
- public int countNodes(TreeNode root) {
- h = mostLeftLevel(root,1);
- if(root == null)
- return 0;
- return bs(root,1);
- }
- public int bs(TreeNode node,int level) {
- if(level == h)
- return 1;
- if(mostLeftLevel(node.right,level + 1) == h)
- return (1 << (h - level)) + bs(node.right,level + 1);
- return (1 << (h - level - 1)) + bs(node.left,level + 1);
- }
- public int mostLeftLevel(TreeNode node,int level) {
- while(node != null) {
- level++;
- node = node.left;
- }
- return level - 1;
- }
- }