[Leetcode] 0101. 对称二叉树

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

 

进阶:你可以运用递归和迭代两种方法解决这个问题吗?

解法

方法一:递归

我们设计一个函数 \(dfs(root1, root2)\),用于判断两个二叉树是否对称。答案即为 \(dfs(root, root)\)

函数 \(dfs(root1, root2)\) 的逻辑如下:

  • 如果 \(root1\)\(root2\) 都为空,则两个二叉树对称,返回 true
  • 如果 \(root1\)\(root2\) 中只有一个为空,或者 \(root1.val \neq root2.val\),则两个二叉树不对称,返回 false
  • 否则,判断 \(root1\) 的左子树和 \(root2\) 的右子树是否对称,以及 \(root1\) 的右子树和 \(root2\) 的左子树是否对称,这里使用了递归。

时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 是二叉树的节点数。

方法二:非递归迭代

「方法一」中我们用递归的方法实现了对称性的判断,那么如何用迭代的方法实现呢?首先我们引入一个队列,这是把递归程序改写成迭代程序的常用方法。初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

时间复杂度:\(O(n)\),同「方法一」。
空间复杂度:这里需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 \(n\) 个点,故渐进空间复杂度为 \(O(n)\)

Python3

递归

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def dfs(self,root1,root2):
        if not root1 and not root2:
            return True
        elif not root1 or not root2:
            return False
        elif root1.val != root2.val:
            return False
        else:
            return self.dfs(root1.left,root2.right) and self.dfs(root1.right,root2.left)
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        return self.dfs(root.left,root.right)

迭代

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def check(self,u,v):
        q = deque([])
        q.append(u)
        q.append(v)
        while(q):
            u = q.popleft()
            v = q.popleft()
            if(not u and not v):
                continue
            if((not u or not v) or (u.val != v.val)):
                return False
            q.append(u.left)
            q.append(v.right)
            q.append(u.right)
            q.append(v.left)
        return True
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        return self.check(root.left,root.right)

C++

递归

/**
 * 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 dfs(TreeNode* root1,TreeNode* root2){
        if(!root1 && !root2)
            return true;
        else if(!root1 ||!root2)
            return false;
        else if(root1->val != root2->val)
            return false;
        else
            return dfs(root1->left,root2->right) && dfs(root1->right,root2->left);
    }
    bool isSymmetric(TreeNode* root) {
        return dfs(root->left,root->right);
    }
};

迭代

/**
 * 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 check(TreeNode *u,TreeNode *v){
        queue<TreeNode*> q;
        q.push(u);
        q.push(v);
        while(!q.empty()){
            u = q.front();q.pop();
            v = q.front();q.pop();
            if(!u && !v) continue;
            if((!u || !v) || (u->val !=v->val))
                return false;
            q.push(u->left);
            q.push(v->right);
            q.push(u->right);
            q.push(v->left);
        }
        return true;
    }
    bool isSymmetric(TreeNode* root) {
        return check(root->left,root->right);
    }
};
posted @ 2023-10-25 09:49  野哥李  阅读(16)  评论(0编辑  收藏  举报