【Java】【JS】LeetCode - 递归 - # 101 对称二叉树

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
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章