題目:
給定一棵完全二叉樹的根節點root,返回這棵樹的節點個數。如果完全二叉樹的節點數爲N,請實現時間複雜度低於O(N)的解法。
給定樹的根結點root,請返回樹的大小。
解題思路:
1.通過找到二叉樹最左的節點,得到樹的高度
2.找到右子樹的最左的節點,如果兩者在同一層,那麼說明左子樹是滿二叉樹,通過公式計算左子樹的節點數。利用遞歸函數繼續求解右子樹的節點數。值得注意的是當求解右子樹的節點數時,根節點變成了原來根節點的右節點,樹高度是原來樹高-1.
如果兩者不在同一層,說明右子樹是滿二叉樹,通過公式計算右子樹的節點數。同樣利用遞歸函數求解左子樹的節點數。最終返回結果是左子樹節點樹+根節點數1+右子樹節點數。
Java代碼:
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class CountNodes {
public int count(TreeNoderoot) {
if(root==null)
{
return -1;
}
returnbs(root,1,mostleftlevel(root,1));
}
public int bs(TreeNodenode,int l,int h)
//l是記錄樹高的起始值,h是樹的高度
{
if(l==h)
{
return 1;
}
//如果右子樹的最左節點的層數與樹的高度相同
//計算右子樹的高度時,level的起始值爲l,右子樹的高度應該比樹高度少1
if(mostleftlevel(node.right,l)==h-1)
{//說明左子樹是滿二叉樹,則節點爲左子樹節點數+頭結點數1+右子樹節點數
//數高n,左子樹的節點數爲2^(n-1)-1,頭結點1,那麼左子樹+頭結點=2^(n-1);
//右子樹的節點數通過遞歸函數來實現,
return(1<<(h-l))+bs(node.right,l,h-1);
}else
{//說明右子樹是滿二叉樹,右子樹的高度爲n-1
return(1<<(h-l-1)+bs(node.left,l,h-1));
}
}
//左子樹的高度
public int mostleftlevel(TreeNodenode,int level)
{
while(node!=null)
{
level++;
node=node.left;
}
return level-1;//因爲最後一個節點是level加了1,所以最後的結果應該level-1
}
}