微信公众号:路人zhang
扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: 算法 > 剑指offer > 剑指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


题解 1

(BFS,递归) O(n)

判断一棵树是否是镜像对称的,需要递归判断左右两个子树是否是镜像对称的。

两个子树镜像对称当前仅当:

  1. 两个子树的根节点相等。
  2. 第一棵子树的左子树和第二棵子树的右子树镜像对称,且第一棵子树的右子树和第二棵子树的左子树镜像对称。

注意:

  1. 两个节点互为镜像的递归出口条件是两个空节点互为镜像。
  2. 递归函数的含义:判断两棵子树是否镜像对称

时间复杂度

每个节点从上到下最多被遍历一次,所以时间复杂度为 O(n)。

空间复杂度

O(logn),最坏情况下二叉树层链状,空间复杂度为 O(n)。

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 dfs(TreeNode* p, TreeNode * q) {
        if (!p && !q) return true;
        if (!p || !q || p->val != q->val) return false;
        return dfs(p->left, q->right) && dfs(p->right, q->left);
    }

    bool isSymmetric(TreeNode* root) {
        if (!root) return true;
        return dfs(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 {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return dfs(root.left, root.right);
    }

    private boolean dfs(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if (p == null || q == null || p.val != q.val) {
            return false;
        }
        return dfs(p.left, q.right) && dfs(p.right, q.left);
    }
}

Python 代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if not root:
            return True
        return self.dfs(root.left, root.right)
    
    def dfs(self, p: TreeNode, q: TreeNode) -> bool:
        if not p and not q:
            return True
        if not p or not q or p.val != q.val:
            return False
        return self.dfs(p.left, q.right) and self.dfs(p.right, q.left)

题解 2

(BFS,迭代) O(n)

使用队列来存储两个子树中要比较的节点,每次从队头取两个节点(左子树的左孩子和右子树的右孩子或者左子树的右孩子和右子树的左孩子)判断是否互为镜像。

其他的思路和递归是一样的。同时用栈也可以。

时间复杂度

每个节点从上到下最多被遍历一次,所以时间复杂度为 O(n)。

空间复杂度

O(logn),最坏情况下二叉树层链状,空间复杂度为 O(n)。

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) return true;
        queue<TreeNode*> q;
        q.push(root->left), q.push(root->right);

        while (q.size()) {
            auto l = q.front(); q.pop();
            auto r = q.front(); q.pop();

            if (!l && !r) continue;
            if (!l || !r || l->val != r->val) return false;

            q.push(l->left), q.push(r->right);
            q.push(l->right), q.push(r->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> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);

        while (!queue.isEmpty()) {
            TreeNode l = queue.poll();
            TreeNode r = queue.poll();

            if (l == null && r == null) {
                continue;
            }
            if (l == null || r == null || l.val != r.val) {
                return false;
            }

            queue.offer(l.left);
            queue.offer(r.right);
            queue.offer(l.right);
            queue.offer(r.left);
        }

        return true;
    }
}

Python 代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if not root:
            return True
        queue = deque()
        queue.append(root.left)
        queue.append(root.right)

        while queue:
            l = queue.popleft()
            r = queue.popleft()

            if not l and not r:
                continue
            if not l or not r or l.val != r.val:
                return False

            queue.append(l.left)
            queue.append(r.right)
            queue.append(l.right)
            queue.append(r.left)

        return True

本文由读者提供Github地址:https://github.com/tonngw


点击面试手册,获取本站面试手册PDF完整版