LeetCode[110/102/111]平衡二叉树、二叉树的层序遍历、二叉树的最小深度 C/C++——Week 2 III

101.平衡二叉树

题目描述[简单]:

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例1:
输入:root = [3,9,20,null,null,15,7]
输出:true
1

思路[递归]:

为了避免重复计算,我们在此处采用的是二叉树的后序遍历。
先检查左子树,获取左子树的高度L;
再检查右子树,获取右子树的高度R;
最后检查L与R的差值是否≤1,若≤1,则满足平衡二叉树的条件。(这里可以用abs()来进行差值运算)

C++代码:

题解1:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    bool isBalanced(TreeNode* root) {
    
    
        return getheigh(root) >= 0;

    }
    int getheigh(TreeNode* root){
    
    
        if(root == nullptr)//其他表示二叉树的高度
        return 0;
        int lefth = getheigh(root -> left);//求左子树高度
        int righth = getheigh(root -> right);//求右子树高度
        if(abs(lefth-righth) <= 1 && lefth >= 0 && righth >=0 ){
    
    
       return max(lefth,righth) + 1;
       } 
       else{
    
    
           return -1;//用-1来表示二叉树不平衡的情况
       }
    }
};

题解2:

class Solution {
    
    
public:
    bool isBalanced(TreeNode* root) {
    
    
        return getheigh(root) != -1;

    }
    int getheigh(TreeNode* root){
    
    
        if(root == nullptr)//其他表示二叉树的高度
        return 0;
        int lefth = getheigh(root -> left);//求左子树高度
        if(lefth == -1)
        return -1;//用-1来表示二叉树不平衡的情况
        int righth = getheigh(root -> right);//求右子树高度
        if(righth == -1)
        return -1;
        if(abs(lefth-righth) > 1 )
        return -1;

       return max(lefth,righth) + 1;
        
    }
};

时间复杂度:O(n);

102.二叉树的层序遍历

题目描述[中等]:

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例1:
输入:root = [3,9,20,null,null,15,7]

输出:[[3],[9,20],[15,7]]
在这里插入图片描述

思路[BFS遍历使用队列]:

初始让根节点入队
1.获取队列的元素个数,为count(之后左右孩子都要入队,因此我们要用count进行区分)
2.依次弹出队列中的全部节点,访问该节点,确保左右孩子都要入队(遍历count次)

扫描二维码关注公众号,回复: 15119096 查看本文章

C++代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
    
    
        vector<vector<int>> res;
        if (root == nullptr) ///若根节点为空,直接返回0
        return res;

        queue<TreeNode*> q; //定义一个队列
        q.push(root);//添加根节点

        while(!q.empty()) {
    
    //当队列非空
            int count = q.size();//获取队列节点数量,即当前节点数
            //现在队列中存储的就是当前队列的全部节点,我们现在要将他们全部取出来存到数组里就好了
            vector<int> c;//定义存储全部节点的数组
            for (int i = 0; i < count; i++) {
    
    
                TreeNode* node = q.front(); 
                q.pop();
               c.push_back(node->val);//把弹出的节点加到数组中
                if (node->left)    //否则把他们左右孩子加进来
                q.push(node->left);
                if (node->right)  
                q.push(node->right);
            }
            res.push_back(c);//每加完一层,层数都要加1
        }

        return res;
    }
};

时间复杂度:O(n);

111.二叉树的最小深度

题目描述[简单]:

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

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

示例1:

输入:root = [3,9,20,null,null,15,7]

输出:2

2

思路[递归]:

找出最小深度其实就是求从根节点到叶子节点的最短路径长度。
本题我们可以用层序遍历、广度优先、长度优先的方法来解答此题。

但是我们可以就单纯只用递归加上三目运算来求解本题。(但是此方法执行时间和内存时间都较大)

C++代码:

思路1【递归+三目运算】:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    int minDepth(TreeNode* root) {
    
    
        if(root == nullptr)
            return 0;
        int left=minDepth(root->left)
        int right=minDepth(root->right);
        return (left && right) ? 1+min(left,right) : 1 + left + right;
    }
};

在三目运算符下,因为最左侧的条件:(left && right),所以实际1 + left + right执行时该节点最多存在一个子树(1 + left + 0 || 1 + right + 0)或为叶子结点(1 + 0 + 0)。

思路2【DFS】:

class Solution {
    
    
public:
    int minDepth(TreeNode* root) {
    
    
        // 判断是不是空树,只有第一次有用,后面递归用不到
        if (root ==nullptr)   
        return 0;
        // 说明为叶子节点,深为1
        if (root->left == nullptr && root->right == nullptr)
        return 1;
        // 左空右不空,返回右子树深度且+1
        if (root->left == nullptr)    
        return minDepth(root->right) + 1;
        // 右空左不空,返回左子树深度且+1
        if (root->right == nullptr)   
        return minDepth(root->left) + 1;
        // 左右都不空,返回左右子树深度较小值且+1
        return min(minDepth(root->left), minDepth(root->right)) + 1; // 判断是不是空树,但只在第一次遍历时使用
    }
};

思路3【层序遍历】:

class Solution {
    
    
public:
    int minDepth(TreeNode* root) {
    
    
        if (root == nullptr) ///若根节点为空,直接返回0
        return 0;

        queue<TreeNode*> q; //定义一个队列
        q.push(root);//添加根节点

        int res = 1;//定义一下结果遍历,初始深度为1

        // 层数从1开始,到了当前层找到叶子节点,那答案就是当前层数
        while(!q.empty()) {
    
    //当队列非空
            int count = q.size();//获取队列节点数量,即当前节点数
            for (int i = 0; i < count; i++) {
    
    //弹出
                TreeNode* node = q.front(); //帮他们把左右孩子加入进来
                q.pop();
                if (node->left == nullptr && node->right == nullptr)   //如果弹出的是叶子节点,就可以直接返回结果
                return res;
                if (node->left)    //否则把他们左右孩子加进来
                q.push(node->left);
                if (node->right)  
                q.push(node->right);
            }
            res++;//每加完一层,层数都要加1
        }

        return res;

    }
};

时间复杂度:O(n);

猜你喜欢

转载自blog.csdn.net/Lailalalala/article/details/126150537