【LeetCode】day14:226 - 翻转二叉树, 101 - 对称二叉树, 104 - 二叉树的最大深度, 111 - 二叉树的最小深度

226.翻转二叉树

题目描述:

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

使用递归处理(迭代以及层序同理),流程为将当前节点左右对调->翻转左节点->翻转右节点,代码如下:

class Solution {
private:
    void reverse(TreeNode* root) {
        if (root == nullptr) return;
        swap(root->left, root->right);
        reverse(root->left);
        reverse(root->right);
    }

public:
    TreeNode* invertTree(TreeNode* root) {
        reverse(root);
        return root;
    }
};

101.对称二叉树

题目描述:

给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
在这里插入图片描述
输入:root = [1,2,2,3,4,4,3]
输出:true

判断二叉树是否轴对称,即依次判断:从根节点出发分别往左往右出发,当前节点值是否相等(若存在),以及左节点的右节点和右节点的左节点是否轴对称。
若left和right均为nullptr也表示相等,而仅有一个为空则不相等。在开始时相当于两指针指向root,代码如下:

class Solution {
private:
    bool traverse(TreeNode* left, TreeNode* right) {
        if (!left && !right) return true;
        if (!left || !right) return false;
        if (left->val != right->val) return false;
        bool flag1 = traverse(left->left, right->right);
        bool flag2 = traverse(left->right, right->left);
        return flag1 && flag2;
    }

public:
    bool isSymmetric(TreeNode* root) {
        return traverse(root, root);
    }
};

同样的思路,作为迭代法的练习,另一种写法:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        stack<TreeNode*> stk;
        stk.push(root);
        stk.push(root);
        while (!stk.empty()) {
            TreeNode* left = stk.top(); stk.pop();
            TreeNode* right = stk.top(); stk.pop();
            if (!left && !right) continue;
            if (!left || !right || left->val != right->val) return false;
            stk.push(left->left);
            stk.push(right->right);
            stk.push(left->right);
            stk.push(right->left);
        }
        return true;
    }
};

104.二叉树的最大深度

题目描述:

给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

思路为遍历二叉树,对于当前节点作为根节点的节点,其最大深度为左子树的最大深度和右子树的最大深度中的最大值加一。代码如下:

class Solution {
private:
    int traverse(TreeNode* root) {
        if (root == nullptr) return 0;
        int leftDepth = traverse(root->left);
        int rightDepth = traverse(root->right);
        return max(leftDepth, rightDepth) + 1;
    }

public:
    int maxDepth(TreeNode* root) {
        return traverse(root);
    }
};

因为是遍历二叉树,同样可以选择使用层序遍历法,对q是否为empty进行判断的外层循环的次数就是树的深度。代码如下:

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> q;
        q.push(root);
        int depth = 0;
        while (!q.empty()) {
            int size = q.size();
            while (size--) {
                TreeNode* cur = q.front();
                q.pop();
                if (cur->left) q.push(cur->left);
                if (cur->right) q.push(cur->right);
            }
            ++depth;
        }
        return depth;
    }
};

111.二叉树的最小深度

题目描述:

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

思路与上题大致相同,特别的是只有当节点的左右节点均为nullptr时该节点才为叶子节点,此时方才计入最小深度的统计中,其余情况须继续遍历。代码如下:

class Solution {
private:
    int traverse(TreeNode* root) {
        if (!root->left && !root->right) return 1;
        int minDepth = INT32_MAX;;
        if (root->left != nullptr) {
            minDepth = traverse(root->left);
        }
        if (root->right != nullptr) {
            minDepth = min(minDepth, traverse(root->right));
        }
        return 1 + minDepth;
    }

public:
    int minDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        return traverse(root);
    }
};

同理使用层序遍历时,对于当前层若出现叶子节点(!cur->left && !cur->right),则当前的深度就是最小深度(因为是首次遇见叶子节点),返回即可。层序遍历代码如下:

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> q;
        q.push(root);
        int depth = 0;
        while (!q.empty()) {
            int size = q.size();
            ++depth;
            while (size--) {
                TreeNode* cur = q.front();
                q.pop();
                if (!cur->left && !cur->right) {
                    return depth;
                }
                if (cur->left) q.push(cur->left);
                if (cur->right) q.push(cur->right);
            }
        }
        return depth;
    }
};
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值