101. 对称二叉树
题意:
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3]
是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3]
则不是镜像对称的:
1
/ \
2 2
\ \
3 3
解题思路:
脑回路:
问 答 什么是对称? 左子树节点的左孩子全部等于右子树的右孩子 如何判断对称? 每次都取相应的节点来比较两个数的值是否相等 怎么取到相对于的值? 左边取左孩子,右边去右孩子.类似于层序,先后有顺序,用队列. 队列怎么判断两个字数? 两个队列存储两个字数,左子树的左孩子与右子树的右孩子比较. 怎样去比较? **左子树先压左孩子,右子树先压右孩子.**这样就可以看是否对称 如果有空节点呢? 如果有空姐点,那么判断是否两边都为空节点,如果是就弹出继续,如果不是就不对称 这时候就已经完成了大致想法,
- 用两个队列,左队列先压左孩子,右队列先压右孩子.
- 每次比较两个队列的值是否相等,不同就不对称.
- 直到有一个队列为空,如果两个队列同时为空,就是对称的,
代码:
/**
* 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 isSymmetric(TreeNode* root) {
queue<TreeNode *>que_left;
queue<TreeNode *>que_right;
if (!root)
return root;
que_left.push(root->left);
que_right.push(root->right);
while (!que_left.empty() && !que_right.empty())
{
TreeNode *q_left = que_left.front();
TreeNode *q_right = que_right.front();
if (q_left == nullptr || q_right == nullptr) //如果有空节点
{
//两边同时为空
if (q_left == nullptr && q_right == nullptr)
{
que_left.pop();
que_right.pop();
continue;
}
//有一边不是空的
return false;
}
//比较两个队列的头节点是否相等
if (q_left->val != q_right->val)
return false;
//头节点出列,然后压入子节点
que_left.pop();
que_right.pop();
//左子树压数据
que_left.push(q_left->left);
que_left.push(q_left->right);
//右子树压数据,先压右孩子
que_right.push(q_right->right);
que_right.push(q_right->left);
}
//如果两个队列同时为空,那么就是对称的
if (que_left.empty() && que_right.empty())
return true;
return false;
}
};
递归解题思路:
二叉树的题基本都可以用递归来完成,想法如下;
问 答 什么时候终止递归? 左边或者右边同时为空, 左边和右边有一个不为空 , 两个节点的值不同 终止递归需要做什么? 不用,直接返回即可 **用什么节点完成递归? ** 使用两节点 left
和right
,先压入left
的左孩子和right
的右孩子.再压入left
的右孩子和right
的左孩子.单层递归 判断是否需要是相同的,获得传入的两个孩子是否同时为true.如果两边有一个为false,那么直接为false;
- 到这里递归基本就已经完成了,代码如下:
/**
* 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 && !right)
return true;
//如果有一遍不为空或者值不同
if (!left || !right || left->val != right->val)
return false;
//两个孩子比较的结果要同时为真才为真,如果有一个假结果就为假
return compare(left->left, right->right) && compare(left->right, right->left);
}
bool isSymmetric(TreeNode* root) {
if (!root)
return true;
return compare(root->left, root->right);
}
};
总结:
题目总体难度不大,迭代需要理解的地方是如何比较相应的两个节点.