代码随想录算法训练营第十四天|LeetCode226.翻转二叉树、LeetCode101. 对称二叉树、LeetCode104.二叉树的最大深度、LeetCode111.二叉树的最小深度

目录

前言

一、LeetCode226.翻转二叉树

题目链接:

题目思路:

前序遍历代码:

后序遍历代码:

 中序遍历代码:

 层序遍历代码:

二、LeetCode101. 对称二叉树

题目链接:

题目思路:

后序遍历代码:

三、LeetCode104.二叉树的最大深度

题目链接:

二叉树的深度和高度:

题目思路:

后序遍历思想:

层序遍历思想:

后序遍历代码:

层序遍历代码:

四、LeetCode111.二叉树的最小深度

题目链接:

题目思路:

后序遍历思想:

层序遍历思想:

后序遍历代码:

层序遍历代码:


前言

LeetCode226.翻转二叉树

视频讲解:LeetCode:226.翻转二叉树_哔哩哔哩_bilibili

文章讲解:代码随想录

LeetCode101. 对称二叉树

视频讲解:LeetCode:101. 对称二叉树_哔哩哔哩_bilibili

文章讲解:代码随想录

LeetCode104.二叉树的最大深度

视频讲解:LeetCode:104.二叉树的最大深度_哔哩哔哩_bilibili

文章讲解:代码随想录

LeetCode111.二叉树的最小深度

视频讲解:LeetCode:111.二叉树的最小深度_哔哩哔哩_bilibili

文章讲解:代码随想录


一、LeetCode226.翻转二叉树

题目链接:

226. 翻转二叉树 - 力扣(LeetCode)

题目思路:

可以通过遍历到每个结点,然后交换左右结点的指针就可以实现如下图的翻转变换。

其中可以通过递归法(前中后序遍历),也可以通过层序遍历

前序遍历代码:

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr) return root;
        swap(root->left, root->right);
        invertTree(root->left);
        invertTree(root->right);

        return root;
    }
};

后序遍历代码:

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr) return root;
        invertTree(root->left);
        invertTree(root->right);
        swap(root->left, root->right);

        return root;
    }
};

 中序遍历代码:

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr) return root;
        invertTree(root->left);
        swap(root->left, root->right);
        // 中序遍历中第二次也是传入的也是left,因为
        // 第一次invertTree已经将左右子树进行互换了
        // 所以要先遍历原先的右子树,就要把变换后的
        // 原右子树的位置(root->left)传入
        invertTree(root->left);

        return root;
    }
};

 层序遍历代码:

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr)
            return root;
        queue<TreeNode *> que;
        que.push(root);
        while(!que.empty())
        {
            TreeNode *pCur = que.front();
            que.pop();
            swap(pCur->left, pCur->right);
            if(pCur->left != nullptr)
                que.push(pCur->left);
            if(pCur->right != nullptr)
                que.push(pCur->right);
        }

        return root;
    }
};

二、LeetCode101. 对称二叉树

题目链接:

101. 对称二叉树 - 力扣(LeetCode)

题目思路:

如果二叉树如下图一样是对称的,那么二叉树外侧结点必须是一致的,内侧结点也要是一致的。也就是说从根节点开始,我们传入左右子树进行判断,让左右子树的外侧之间和内侧之间的结点进行判断,既要保证结点个数相同,又要保证结点的值相同才能得到对称的二叉树。

后序遍历代码:

/**
 * 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 compare(TreeNode *left, TreeNode *right)
    {
        // 如果左右结点一边为nullptr,一边不为nullptr,那么一定不对称
        if(left == nullptr && right != nullptr)
            return false;
        else if(left != nullptr && right == nullptr)
            return false;
        // 如果左右结点都为nullptr,则左右结点肯定是对称的
        else if(left == nullptr && right == nullptr)
            return true;
        // 如果左右结点的值不同,也代表左右结点不对称
        else if(left->val != right->val)
            return false;
        
        // 左右子树的外侧进行比较
        bool outside = compare(left->left, right->right);
        // 左右子树的内侧进行比较
        bool inside = compare(left->right, right->left);

        return outside && inside;
    }
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr) return true;

        return compare(root->left, root->right);
    }
};

三、LeetCode104.二叉树的最大深度

题目链接:

104. 二叉树的最大深度 - 力扣(LeetCode)

二叉树的深度和高度:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从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 getHeight(TreeNode* root)
    {
        if(root == nullptr)
            return 0;
        
        int leftHeight = getHeight(root->left);
        int rightHeight = getHeight(root->right);

        return 1 + max(leftHeight, rightHeight);
    }

    int maxDepth(TreeNode* root) {
        return getHeight(root);
    }
};

层序遍历代码:

/**
 * 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 maxDepth(TreeNode* root) {
        if(root == nullptr) return 0;
        int layerNum = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty())
        {
            int size = que.size();
            TreeNode *pCur = nullptr;
            while(size--)
            {
                pCur = que.front();
                que.pop();
                if(pCur->left)
                    que.push(pCur->left);
                if(pCur->right)
                    que.push(pCur->right);
            }
            layerNum++;
        }

        return layerNum;
    }
};

四、LeetCode111.二叉树的最小深度

题目链接:

111. 二叉树的最小深度 - 力扣(LeetCode)

题目思路:

后序遍历思想:

后序遍历首先要考虑两种情况,第一,结点的左子树为空,右子树不为空的情况。第二,结点的右子树为空,左子树不为空的情况。这两种情况下如果我们直接返回了空子树的高度,那得到的就会是一个错误的值,要想到深度是根节点到叶子结点,如果直接返回了空子树的高度,那得到的就不是根节点到叶子结点的距离了。所以在函数返回的时候要分情况进行讨论。

层序遍历思想:

最小深度的思想跟最大深度的遍历思想一致,尤其是在层序遍历上,只是多了一个退出条件,就是当检测到第一个叶子结点后就退出并返回当前层数

后序遍历代码:

/**
 * 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 getHeight(TreeNode *root)
    {
        if(root == nullptr) return 0;

        int leftHeight = getHeight(root->left);
        int rightHeight = getHeight(root->right);

        if(root->left == nullptr && root->right != nullptr)
            return rightHeight + 1;
        else if(root->left != nullptr && root->right == nullptr)
            return leftHeight + 1;
        
        return min(leftHeight, rightHeight) + 1;
    }

    int minDepth(TreeNode* root) {
        return getHeight(root);
    }
};

层序遍历代码:

/**
 * 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;
        queue<TreeNode *> que;
        que.push(root);
        int layerNum = 1;
        while(!que.empty())
        {
            int size = que.size();
            TreeNode *pCur = nullptr;
            while(size--)
            {
                pCur = que.front();
                que.pop();
                if(pCur->left == nullptr && pCur->right == nullptr)
                    return layerNum;
                else
                {
                    if(pCur->left)
                        que.push(pCur->left);
                    if(pCur->right)
                        que.push(pCur->right);
                }
            }
            layerNum++;
        }
        return layerNum;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值