輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
我本來想的是用dfs,每個節點遞歸,然后回溯看右節點,但是發現不會寫。這個遞歸還是沒有理解好,dfs跟bfs也不熟練,這兩個方法使用來遍歷圖的,圖是樹的特殊狀態(個人觀點),所以主要還是算法的本質掌握的不熟練。那這道題呢,有兩個方法。
1.平衡二叉樹是任意節點的左右子樹深度相差不能為1的,所以我們可以計算每個節點的深度,來看這顆樹是不是平衡的。
class Solution
{
public:
bool IsBalanced_Solution(TreeNode* pRoot)
{
if(!pRoot) return true;
int left = getdepth(pRoot->left);
int right = getdepth(pRoot->right);
if(abs(left-right)>1)
return false;
return(IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right));
}
//遞歸實現,dfs
int getdepth(TreeNode* pRoot)
{
if(!pRoot) return 0;
int left = getdepth(pRoot->left);
int right = getdepth(pRoot->right);
return max(left+1,right+1);
}
//迭代,bfs
int getdepth(TreeNode* pRoot)
{
if(!pRoot) return 0;
queue<TreeNode*> que;
que.push(pRoot);
int depth =0;
while(!que.empty())
{
int size = que.size();
++depth;
for(int i=0;i<que.size();++i)
{
TreeNode* temp = que.front();
que.pop();
if(temp->left)
que.push(temp->left);
if(temp->right)
que.push(temp->right);
}
}
return depth;
}
}
那么這個呢是根據每個節點的深度來判斷這棵樹是不是平衡二插樹。算深度的算法使用了迭代和遞歸兩種方法來實現。這個算法有個問題就是,判斷true/false只在is那個函數里面判斷了,所以我們要每個節點都遍歷,這樣下層的節點實際上我們就走了很多次。這個是很浪費時間的。所以就有第二個算法。
2
class Solution
{
public:
bool status = true;
bool IsBalanced_Solution(TreeNode* pRoot)
{
getdepth(pRoot);
return status;
}
int getdepth(TreeNode* pRoot)
{
if(!pRoot) return 0;
int left=getdepth(pRoot->left);
int right=getdepth(pRoot->right);
if(abs(left-right)>1)
status = false;
return max(left+1,right+1);
}
}
這個方法看上去跟上一個類似,但是還有區別的。上一個只在is函數里面才有false/true,并且每個is函數都要調用一下getdepth函數。所以每個節點會計算很多啊遍。
而第二個方法在getdepth中有true和false,只要有一個節點不滿足平衡就返回false,并且getdepth只計算了一次全部的節點,沒有多余的計算。
以上。