用递归思路很清晰
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if (root == null)
return 0;
int count = 0;
count++;
count += countNodes(root.left);
count += countNodes(root.right);
return count;
}
}
当然,你可以简写成这样
public int countNodes(TreeNode root) {
if(root ==null){
return 0;
}
return 1+countNodes(root.left)+countNodes(root.right);
}
以上两种写法是把所有的节点都遍历一遍,所以算不上效率最高的
这道题的考点是,你清不清楚完全二叉树的特点:
(1)叶子结点只能出现在最下两层。
(2)最下层的叶子一定集中在左部连续位置。
(3)倒数二层,若有叶子结点,一定都在右部连续位置。
(4)如果结点度为1,则该结点只有左孩子
(5)同样结点数的二叉树,完全二叉树的深度最小
给人的感觉就是完全二叉树,能排满一层,排满一层,不能排满一层,就先排左边。
public int countNodes(TreeNode root) {
if (root == null)
return 0;
int count = 0;
int leftH = getDepth(root.left);
int rightH = getDepth(root.right);
// 判断左右子树的高度:
// 如果相等说明左子树是满二叉树, 然后进一步判断右子树的节点数
// 如果不等说明右子树是深度小于左子树的满二叉树, 然后进一步判断左子树的节点数
if (leftH == rightH){
// 那么左子树为满二叉树
//1(根节点) + (1 << leftH)-1(左完全左子树节点数) + 右子树节点数量
count += 1 << leftH;
count += countNodes(root.right);
}else {
// 那么右子树为满二叉树
count += 1 << rightH;
count += countNodes(root.left);
}
return count;
}
// public int dfs(TreeNode root){
// return root==null ? 0 : dfs(root.left);
// }
// 完全二叉树的高度可以直接通过不断地访问左子树就可以获取
private int getDepth(TreeNode r) {
int depth = 0;
while(r != null) {
depth++;
r = r.left;
}
return depth;
}