0706【二叉树】102. 二叉树的层序遍历 101. 对称二叉树 104. 二叉树的最大深度 111. 二叉树的最小深度 222. 完全二叉树的节点个数 110. 平衡二叉树

102. 二叉树的层序遍历

    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root)   return {};
        vector<int> tmp;
        vector<vector<int>> ans;
        queue<TreeNode*> que;
        que.push(root);
​
        while( !que.empty() ){
            int size = que.size();
            tmp.clear();        //注意这里 之前没清空
            for( int i = 0; i<size; ++i){
                TreeNode* node = que.front();
                que.pop();
                tmp.push_back(node->val);
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
            }
            ans.push_back(tmp);
        }
        return ans;
    }
101. 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

【分析】:转化成判断两颗树:左子树和右子树

    bool TreeCompare(TreeNode* leftRoot, TreeNode* rightRoot)
    {
        if(!leftRoot && !rightRoot) return true; //到叶子返回
        //两棵树不对称,一个为空
        if((leftRoot && !rightRoot)  || (!leftRoot && rightRoot) )  return false;
        //比较当前结点 左右节点
        if(leftRoot->val != rightRoot->val) return false;
        bool leftRes = TreeCompare(leftRoot->left, rightRoot->right);
        bool rightRes = TreeCompare(leftRoot->right, rightRoot->left);
        return leftRes && rightRes;
    }
    bool isSymmetric(TreeNode* root) {
        //比较两棵树:左右子树
        return TreeCompare(root->left, root->right);
    }
104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

【分析】递归遍历,返回左右子树深度最大+1 开始想遍历到叶子节点,if中判断叶子节点 但是左右递归的时候没有判断导致传入了空指针。

 int getDepth(TreeNode* node){
        if(!node)   return 0; 
        
        int leftDepth = getDepth(node->left);
        int rightDepth = getDepth(node->right);
​
        return leftDepth > rightDepth? leftDepth+1 : rightDepth+1;
    }

2.层序遍历

int maxDepth(TreeNode* root) {
        if(!root)   return 0;
        //层序遍历 记录层数
        int depth = 0;
        queue<TreeNode*> que;
        que.push(root);
        TreeNode* node = nullptr;
        
        while( !que.empty() ){
            depth++;  //每层循环深度+1
            int size = que.size();
            //处理当前层的节点
            for(int i = 0; i<size; ++i){
                node = que.front();
                que.pop();
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return depth;   
    }
111. 二叉树的最小深度

【分析】

1.递归迭代

和最大深度的差别:最大深度直接返回左右最大的哪个

最小深度可能会出现x结点没有左子树,但是有右子树,x并不是叶子节点,不能返回深度更小的左

需要判断处理两种特殊情况,除此之外才能直接比较大小返回小+1

    int getMinDepth(TreeNode* node){
        //找到叶子节点 返回1
        if(!node) return 0;
        //比较当前左右子树 返回最小+1
        int depth = 0;
        int leftDepth = 0, rightDepth = 0;
        leftDepth = getMinDepth(node->left);
        rightDepth = getMinDepth(node->right);
​
        // 当一个左子树为空,右不为空,这时并不是最低点
        if (node->left == NULL && node->right != NULL) { 
            return 1 + rightDepth;
        }   
        // 当一个右子树为空,左不为空,这时并不是最低点
        if (node->left != NULL && node->right == NULL) { 
            return 1 + leftDepth;
        }
        depth = min(leftDepth, rightDepth)+1;
        return depth;
    }

2.层序

还是一样的层序遍历,在每层的处理中 判断当前结点是否是叶子结点,找到的第一个叶子就是深度最小的。直接break返回

    int getMinDepth(TreeNode* node){
        int depth = 0;
        queue<TreeNode*> que;
        que.push(node);
​
        while( !que.empty() ){
            int size = que.size();
            depth++;
            for(int i = 0; i<size; ++i){
                node = que.front();
                que.pop();
                if(node->left)  que.push(node->left);
                if(node->right) que.push(node->right);
                if( !node->left && !node->right)    //判断是否为叶子结点
                    return depth;
            }
        }
        return depth;
    }
 

【分析】

最简单的直接遍历,尝试利用完全二叉树的性质

满二叉树是特殊的完全二叉树,可以在完全二叉树中找满二叉树,利用公式计算满二叉树的节点个数

满二叉树的判断:左深度 == 右深度

1.空 返回

2.左侧深度 右侧深度 如果相等,返回2^n -1;

3.返回 左+右+1;

    int getCount(TreeNode* root){
        if(root == nullptr) return 0;
        int leftDepth = 0, rightDepth = 0;
        TreeNode* pleft = root->left;
        TreeNode* pright = root->right;
        while(pleft){  //左子树深度
            pleft = pleft->left;
            leftDepth++;
        }
        while(pright){ //右子树深度
            pright = pright->right;
            rightDepth++;
        }
        //如果是满二叉树 可以直接计算返回
        if(rightDepth == leftDepth){  
            //如果到叶子节点 2<<0-1 = 1
            return (2 << leftDepth) - 1;
        }
        //不是满二叉树 要计算左右子树
        return getCount(root->left) + getCount(root->right) +1;
    }
    int countNodes(TreeNode* root) {
        return getCount(root);
    }

【注意】 2^n的计算 n>0,实际就是2左移n-1位 2<<(n-1)

110. 平衡二叉树
    int Balanced(TreeNode* node){
        if(node == nullptr) return 0;
        //计算在左右高度
        int ldepth = Balanced(node->left);
        int rdepth = Balanced(node->right);
        //差绝对值<1 是
        if( (ldepth == -1 )|| (rdepth == -1) ) return -1;
        if( abs(ldepth-rdepth) <= 1 ){
            return max(ldepth, rdepth)+1;
        }
        return -1;
    }
    bool isBalanced(TreeNode* root) {
        if(Balanced(root) == -1)  return false;
        return true;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值