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
思考:
本题的目标是判断二叉树的对称性,比较的是所有的左右子树是否相同,这就要求我们在遍历的过程中比较左子树的外层与右子树的外层相同,内侧与内侧相同。
即:
- 左子树2的左孩子 == 右子树2的右孩子
- 左子树2的右孩子 == 右子树2的左孩子
而同样的,在遍历的方式上,我们可以选用递归法或是迭代法。其中,迭代法的本质其实就是层级遍历。
递归法:
递归法的难点就在于找到终止条件,以及每一次递归所要干的事。在本题中,因为要返回的是bool类型值,所以我们的终止条件其实十分简单,即不断判断是否对称,一旦出现不对称的情况,就返回false值。
而不对称的情况莫过于两种:
- 左右结点中有一个为空节点,另一个不为空。
- 左右结点对应的val值不相等。
我们使用深度优先遍历的方法,传入左右两个结点,进行比较,一轮比较结束后,再对内侧两节点以及外侧两节点进行递归比较。
//递归法
class Solution {
public:
bool dfs(TreeNode* left, TreeNode* right)
{
if (left == NULL && right == NULL)
{
return true;
}
if (left == NULL || right == NULL)
{
return false;
}
if (left->val != right->val)
{
return false;
}
return dfs(left->left, right->right) && dfs(left->right, right->left);
}
bool isSymmetric(TreeNode* root) {
//考虑空节点情况
if (root == NULL)
{
return true;
}
return dfs(root->left,root->right);
}
};
迭代法:
而运用迭代法,我们所使用的是最为经典的层序遍历的方式,使用队列这种数据结构(用栈或者数组等都可以),将对应的左右结点先存入队列中,再每一次取出两个结点,进行两两比较即可,一旦出现不对称的情况,则返回false值,若是成功完成全部遍历,则返回true。
//迭代法(层序遍历)
class Solution2
{
public:
bool isSymmetric(TreeNode* root)
{
//判断空节点以及只有根节点的情况
if (root == NULL || (root->left == NULL && root->right == NULL))
{
return true;
}
queue<TreeNode*> que;//初始化队列
que.push(root->left);
que.push(root->right);
while (!que.empty())
{
//从队列中取出结点
TreeNode* left = que.front();
que.pop();
TreeNode* right = que.front();
que.pop();
//进行判断
if (left == NULL && right == NULL)
{
continue;
}
if (left == NULL || right == NULL)
{
return false;
}
if (left->val != right->val)
{
return false;
}
//添加子节点到队列(即使是空节点也加入)
que.push(left->left);
que.push(right->right);
que.push(left->right);
que.push(right->left);
}
return true;
}
};
参考:代码随想录
往期回顾:
LeetCode226. 翻转二叉树
专题一 二叉树层序遍历
LeetCode102. 二叉树的层序遍历
LeetCode144、145、94. 二叉树遍历
LeetCode18. 四数之和
LeetCode15. 三数之和
LeetCode383. 赎金信
LeetCode454. 四数相加 II
LeetCode1. 两数之和
LeetCode202. 快乐数
LeetCode350. 两个数组的交集 II
LeetCode349. 两个数组的交集
LeetCode1002. 查找共用字符