we are nobody,but we are on the way to be somebody!! 力扣力扣 https://leetcode-cn.com/problems/symmetric-tree/
# 101 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
进阶:你可以运用递归和迭代两种方法解决这个问题吗?
方法一:递归
根据题目的描述,镜像对称,就是左右两边相等,也就是左子树和右子树是相当的。
注意这句话,左子树和右子相等,也就是说要递归的比较左子树和右子树。
我们将根节点的左子树记做 left,右子树记做 right。比较 left 是否等于 right,不等的话直接返回就可以了。
如果相当,比较 left 的左节点和 right 的右节点,再比较 left 的右节点和 right 的左节点
比如看下面这两个子树(他们分别是根节点的左子树和右子树),能观察到这么一个规律:
左子树的左孩子 = 右子树的右孩子
左子树的右孩子 = 右子树的左孩子
终止条件:left 和 right 不等,或者 left 和 right 都为空
/* 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;
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right){
if(left == null && right == null){ // 停止条件1:两节点为空,相等
return true;
}
if(left == null || right == null){ // 停止条件2:两者有一者为空,不等
return false;
}
if(left.val != right.val){ // 停止条件3:两者值不同,不等
return false;
}
// 递归比较(左左,右右)&&(左右,右左)
return compare(left.left, right.right)&&compare(left.right, right.left);
}
}
/* javascript
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(root == null){
return true;
}
const check = (left, right)=>{
if(left == null && right == null){
return true;
}else if(left == null || right == null){
return false;
}else{
return left.val === right.val && check(left.left, right.right) && check(left.right, right.left);
}
return false;
}
return check(root.left, root.right);
};
方法二:迭代(队列)
现在我们改用队列来实现,思路如下:
首先从队列中拿出两个节点(left 和 right)比较
(1)将 left 的 left 节点和 right 的 right 节点放入队列
(2)将 left 的 right 节点和 right 的 left 节点放入队列
时间复杂度是 O(n),空间复杂度是 O(n)
// java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null || (root.left == null && root.right == null)){
return true;
}
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root.left);
queue.add(root.right); // 左右子树入队
while(queue.size()>0){
TreeNode left = queue.removeFirst();
TreeNode right = queue.removeFirst(); // 拿出队列前两个元素比较
if(left == null && right == null){
continue; // 注意此时队列可能还有元素,不能return true
}
if(left == null || right == null){
return false;
}
if(left.val != right.val){
return false;
}
queue.add(left.left);
queue.add(right.right);
queue.add(left.right);
queue.add(right.left);
}
return true;
}
}
方法三:栈模拟递归
var isSymmetric = (root) => {
if (!root) return true
let leftStack = [], rightStack = [] // 维护两个栈
let curLeft = root.left // 当前的左子树
let curRight = root.right // 当前的右子树
while (curLeft || curRight || leftStack.length || rightStack.length) {
while (curLeft) { // 左子树存在
leftStack.push(curLeft) // 推入leftStack栈
curLeft = curLeft.left // 不断将左子树入栈
}
while (curRight) { // 右子树存在
rightStack.push(curRight) // 推入rightStack栈
curRight = curRight.right // 不断将右子树压入栈
}
if (leftStack.length !== rightStack.length) return false
// 栈的高度不相等,说明结构不对称
curLeft = leftStack.pop() // 栈顶节点出栈,赋给curLeft
curRight = rightStack.pop() // 栈顶节点出栈,赋给curRight
if (curLeft.val !== curRight.val) return false
// 两个栈出栈的节点值不相等 不对称
curLeft = curLeft.right // 考察左子树的right
curRight = curRight.left // 考察右子树的left
}
return true
}