翻转二叉树
(力扣226题)
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:
输入:root = [2,1,3]
输出:[2,3,1]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目范围在
[0, 100]
内 -100 <= Node.val <= 100
解题思路
- 递归终止条件:如果当前节点为空(
root == NULL
),直接返回NULL
,因为空树的翻转仍然是空树。 - 交换左右子树:对于非空节点,交换其左右子树。这是通过
swap(root->left, root->right)
实现的,是翻转的核心操作。 - 递归处理子树:递归调用
invertTree
函数分别翻转当前节点的左子树和右子树。由于左右子树已经交换,递归调用实际上是翻转交换后的左右子树。 - 返回根节点:递归完成后,返回根节点
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 == NULL)
{
return root;
}
// 交换当前节点的左右子树
swap(root->left, root->right);
// 递归
invertTree(root->left);
invertTree(root->right);
return root;
}
};
对称二叉树
(力扣101题)
给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
提示:
- 树中节点数目在范围
[1, 1000]
内 -100 <= Node.val <= 100
**进阶:**你可以运用递归和迭代两种方法解决这个问题吗?
解题思路
- 递归比较函数:定义一个辅助函数
compare
,用于递归比较两棵树是否镜像对称。 - 处理空节点情况:
- 如果一个节点为空而另一个不为空,直接返回
false
,因为不对称。 - 如果两个节点都为空,返回
true
,因为空树是对称的。
- 如果一个节点为空而另一个不为空,直接返回
- 处理非空节点:
- 如果两个节点的值不相等,返回
false
。 - 如果值相等,递归比较左子树的左节点与右子树的右节点(外层),以及左子树的右节点与右子树的左节点(内层)。
- 如果两个节点的值不相等,返回
- 递归逻辑:通过递归调用
compare
函数,逐层比较两棵树的对应节点是否满足对称条件。 - 主函数:在
isSymmetric
函数中,首先判断根节点是否为空。如果为空,直接返回true
。否则,调用compare
函数比较根节点的左子树和右子树是否对称。
这种方法利用递归的思想,从根节点的左右子树开始,逐层递归比较,确保整棵树的对称性。
代码
/**
* 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)
{
// 首先排除空节点的情况
if(left != NULL && right == NULL) return false;
else if(left == NULL && right != NULL) return false;
else if(left == NULL && right == NULL) return true;
// 排除了空节点,再排除数值不相同的情况
else if(left->val != right->val) return false;
// 此时就是:左右节点都不为空,且数值相同的情况
// 此时才做递归,做下一层的判断
bool outside = compare(left->left, right->right); // 外层循环 左子树:左、 右子树:右
bool intside = compare(left->right, right->left); // 内层循环 左子树:右、 右子树:左
bool isSame = outside && intside;
return isSame;
}
bool isSymmetric(TreeNode* root)
{
if(root == NULL)
{
return true;
}
return compare(root->left, root->right);
}
};
二叉树的 最大深度
(力扣104题)
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:
输入:root = [1,null,2]
输出:2
提示:
- 树中节点的数量在
[0, 104]
区间内。 -100 <= Node.val <= 100
解题思路
- 递归函数:定义一个辅助函数
getheight
,用于递归计算二叉树的高度。 - 递归终止条件:如果当前节点为空(
root == NULL
),返回高度为 0,因为空树的高度为 0。 - 递归计算左右子树高度:
- 递归计算左子树的高度
leftHeight
。 - 递归计算右子树的高度
rightHeight
。
- 递归计算左子树的高度
- 计算当前节点的高度:当前节点的高度等于左右子树高度的最大值加 1(
max(leftHeight, rightHeight) + 1
)。 - 返回结果:在主函数
maxDepth
中,直接调用getheight
函数,返回根节点的高度,即二叉树的最大深度。
这种方法利用递归的思想,通过后序遍历(先计算左右子树高度,再计算当前节点高度)的方式,自底向上计算二叉树的最大深度,简洁高效。
代码
/**
* 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 == NULL) return 0;
//左孩子的高度
int leftHeight = getheight(root->left);
//右孩子的高度
int rightHeight = getheight(root->right);
int depth = max(leftHeight, rightHeight) + 1;
return depth;
}
int maxDepth(TreeNode* root)
{
return getheight(root);
}
};
二叉树的最小深度
(力扣111题)
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
**说明:**叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
提示:
- 树中节点数的范围在
[0, 105]
内 -1000 <= Node.val <= 1000
解题思路
- 递归终止条件:如果当前节点为空(
node == NULL
),返回深度为 0,因为空树的深度为 0。 - 处理特殊情况:
- 如果左子树为空而右子树不为空,返回右子树的深度加 1。这是因为最小深度是从根节点到最近的叶子节点的距离,此时不能通过左子树计算。
- 如果右子树为空而左子树不为空,返回左子树的深度加 1,同理。
- 正常情况:如果左右子树都存在,取左右子树深度的较小值加 1,作为当前节点的最小深度。
- 递归计算:通过递归分别计算左右子树的深度,然后根据上述规则确定当前节点的最小深度。
- 返回结果:在主函数
minDepth
中,调用辅助函数getDepth
,返回根节点的最小深度。
这种方法利用递归的思想,通过分别处理左右子树为空和都存在的不同情况,确保能够正确计算二叉树的最小深度
/**
* 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 getDepth(TreeNode *node)
{
// 递归终止条件
if (node == NULL)
return 0;
//左子树的深度
int leftDepth = getDepth(node->left);
// 右子树的深度
int rightDepth = getDepth(node->right);
// 根节点
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL)
{
return rightDepth + 1;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL)
{
return leftDepth + 1;
}
// 如果是左右子树都存在,取最小的
int result = min(leftDepth, rightDepth) + 1;
return result;
}
int minDepth(TreeNode* root)
{
return getDepth( root);
}
};