剑指offer-面试题39:二叉树的深度

题目一:输入一颗二叉树的根结点,求该树的深度。从根结点到叶结点一次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

思路:如果根结点存在,那么深度至少为1,接下来求左右子树的深度,很明显用递归算法,最后树的深度就是左右子树中深度较大的加上1.

int DepthOfBinaryTree(BinaryTreeNode* pRoot)
{
    if(pRoot == NULL)
        return 0;
        
    int depthOfLeft = DepthOfBinaryTree(pRoot->m_pLeft);
    int depthOfRigth = DepthOfBinaryTree(pRoot->m_pRight);
            
    int longerChild = depthOfLeft > depthOfRigth ? depthOfLeft : depthOfRigth;
    return 1 + longerChild;
}

题目二:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

思路:很容易想到对每个结点求深度的办法,对每一个结点,调用之前求深度的函数判断它的左右子树深度相差是否超过1。但是这种方式重复遍历了树的结点,深度越大的结点,重复的次数越多。这道题与前面求斐波那契数列的情况颇为类似,在那里我们要求f(10),用递归的办法就得先求出f(9)和f(8),继而再求f(8)和f(7),这样就产生了很多重复计算。那里的解决办法是改变求和的次序,先求f(1),接着求f(2)…这样顺序递推,就避免了重复求和的情况。那么回到本题上,和斐波那契数列类似,我们先不判断根结点是否平衡,而是判断最深的父结点是否平衡,同时记录结点的深度,接着在往上遍历,判断是否平衡,直到上升到根结点,这样就避免了重复对结点求深度的情况,实际上就是一个后序遍历的过程。

bool IsBalanced(BinaryTreeNode* pRoot, int* depth)
{
    if(pRoot == NULL)
    {
        *depth = 0;
        return true;
    }
    
    int left, right;
    if(IsBalanced(pRoot->m_pLeft, &left) && IsBalanced(pRoot->m_pRight, &right))
    {
        int diff = left - right;
        if(diff <= 1 && diff >= -1)
        {
            *depth = 1 + (left > right ? left : right);
            return true;
        }
    }
    
    return false;
}

bool IsBalanced(BinaryTreeNode* pRoot)
{
    int depth = 0;
    return IsBalanced(pRoot, &depth);
}


你可能感兴趣的:(剑指offer-面试题39:二叉树的深度)