❓ 剑指 Offer 28. 对称的二叉树
难度:简单
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [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
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
限制:
0 <= 节点个数 <= 1000
注意:本题与 101. 对称二叉树 相同。
💡思路:
法一:递归
如果一个树的左子树与右子树镜像对称,那么这个树是对称的:
- 每次检查当前
root1
和root2
节点的值是否 相等; - 如果 相等 再判断左右子树是否对称:
root1
的 左子树 对应root2
的 右子树 ;root1
的 右子树 对应root2
的 左子树 ;- 同时成立时返回
true
。
法二:迭代
方法一 中我们用 递归 的方法实现了对称性的判断,那么如何用迭代的方法实现呢?
- 要引入一个 队列
q
,这是把递归程序改写成迭代程序的常用方法。
如果 root
不为空,将左右子树根节点分别加入队列:
- 只要队列不为空,每次从队列中提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像);
- 然后将两个结点的左右子树按相反的顺序插入队列中;
- 插入
temp1
的左子树后,紧接着插入temp2
的右子树的根节点; - 然后再插入
temp1
的右子树后,紧接着插入temp2
的左子树的根节点;
- 插入
- 当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
🍁代码:(C++、Java)
法一:递归
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
bool isSymTree(TreeNode* root1, TreeNode* root2){
if(root1 == nullptr && root2 == nullptr) return true;
if(root1 == nullptr || root2 == nullptr || (root1->val != root2->val)) return false;
return isSymTree(root1->left, root2->right) && isSymTree(root1->right, root2->left);
}
public:
bool isSymmetric(TreeNode* root) {
if(root == nullptr) return true;
return isSymTree(root->left, root->right);
}
};
Java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private boolean isSymTree(TreeNode root1, TreeNode root2){
if(root1 == null && root2 == null) return true;
if(root1 == null || root2 == null || (root1.val != root2.val)) return false;
return isSymTree(root1.left, root2.right) && isSymTree(root1.right, root2.left);
}
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymTree(root.left, root.right);
}
}
法二:迭代
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == nullptr) return true;
queue<TreeNode*> q;
q.push(root->left);
q.push(root->right);
while(!q.empty()){
TreeNode* temp1 = q.front();
q.pop();
TreeNode* temp2 = q.front();
q.pop();
if(temp1 == nullptr && temp2 == nullptr) continue;
if(temp1 == nullptr || temp2 == nullptr || (temp1->val != temp2->val)) return false;
q.push(temp1->left);
q.push(temp2->right);
q.push(temp1->right);
q.push(temp2->left);
}
return true;
}
};
Java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.offer(root.left);
q.offer(root.right);
while(!q.isEmpty()){
TreeNode temp1 = q.poll();
TreeNode temp2 = q.poll();
if(temp1 == null && temp2 == null) continue;
if(temp1 == null || temp2 == null || (temp1.val != temp2.val)) return false;
q.offer(temp1.left);
q.offer(temp2.right);
q.offer(temp1.right);
q.offer(temp2.left);
}
return true;
}
}
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
为root
的节点数,遍历了这棵树。 - 空间复杂度:
O
(
n
)
O(n)
O(n),法一 的空间复杂度和递归使用的栈空间有关,这里递归层数不超过
n
; 法二 需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过n
个点。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!