#P4055. 对称二叉树
-
ID: 2297
Tried: 76
Accepted: 31
Difficulty: 3
对称二叉树
题目内容
给你一个二叉树的根节点 root , 检查它是否轴对称。
输入描述
一行包含二叉树的序列化数组,节点值之间用空格隔开,空节点用null表示。
输出描述
- 若二叉树是轴对称的,输出 true;
- 否则,输出 false。
样例1
输入
1 2 2 3 4 4 3
输出
true
样例2
输入
1 2 2 null 3 null 3
输出
false
提示
- 树中节点数目在范围 [0,100] 内
- −100<=Node.val<=100
判断二叉树是否轴对称
题目理解
题目要求检查一棵二叉树是否是轴对称的,即判断这棵树是否为镜像二叉树。镜像二叉树的定义是:对于树中的每一个节点,其左子树与右子树互为镜像。
解题思路
递归方法
利用递归的方式,我们可以判断两棵子树是否镜像对称。具体而言:
- 若树为空(
root == null
),直接返回true
。 - 若树非空,则检查左右子树是否镜像对称:
- 根节点的左右子树值必须相等。
- 左子树的左子树与右子树的右子树要相等。
- 左子树的右子树与右子树的左子树要相等。
设定一个辅助函数 isMirror(left, right)
来递归检查左右子树是否镜像。
时间复杂度分析:
- 每个节点都会被访问一次,时间复杂度为 O(n),其中
n
是二叉树的节点个数。 - 递归的深度最多为
O(h)
,其中h
是树的高度,最坏情况下h=O(n)
(退化为链表)。
迭代方法(队列)
我们也可以使用队列来判断树是否对称。思路如下:
- 初始时,将
root
的左右子节点分别入队。 - 逐步从队列中取出两个节点:
- 若两者均为空,继续下一轮。
- 若仅一个为空或值不同,则直接返回
false
。 - 继续入队:左子树的左子节点和右子树的右子节点、左子树的右子节点和右子树的左子节点。
时间复杂度:
- 仍然是 O(n),因为每个节点被访问一次。
- 但空间复杂度为
O(n)
(BFS 队列在最坏情况下存储O(n)
级别的节点)。
代码实现
Python 递归实现
from typing import Optional, List
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
# 辅助函数:判断两个子树是否镜像对称
def isMirror(left: Optional[TreeNode], right: Optional[TreeNode]) -> bool:
if not left and not right:
return True
if not left or not right:
return False
return (left.val == right.val and
isMirror(left.left, right.right) and
isMirror(left.right, right.left))
return isMirror(root.left, root.right)
# 辅助函数:列表转二叉树
def buildTree(nodes: List[Optional[int]]) -> Optional[TreeNode]:
if not nodes or nodes[0] == 'null' or nodes[0] is None:
return None
# 将首元素作为根节点
root = TreeNode(int(nodes[0]))
queue = [root]
idx = 1 # 从第二个元素开始
while queue and idx < len(nodes):
current = queue.pop(0)
# 构建左子节点
if idx < len(nodes) and nodes[idx] != 'null' and nodes[idx] is not None:
current.left = TreeNode(int(nodes[idx]))
queue.append(current.left)
idx += 1
# 构建右子节点
if idx < len(nodes) and nodes[idx] != 'null' and nodes[idx] is not None:
current.right = TreeNode(int(nodes[idx]))
queue.append(current.right)
idx += 1
return root
# 读取输入并执行
if __name__ == "__main__":
values = input().split()
tree = buildTree([int(v) if v != 'null' else None for v in values])
solution = Solution()
print(solution.isSymmetric(tree))
Java 递归实现
import java.util.*;
public class Main {
public class Solution {
// 定义二叉树节点
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) { val = x; }
}
// 判断是否是对称二叉树
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isMirror(root.left, root.right);
}
// 递归检查两个子树是否镜像对称
private boolean isMirror(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
if (left == null || right == null) return false;
return (left.val == right.val)
&& isMirror(left.left, right.right)
&& isMirror(left.right, right.left);
}
// 辅助函数:根据数组构造二叉树
public TreeNode buildTree(String[] nodes) {
if (nodes.length == 0 || nodes[0].equals("null")) {
return null;
}
// 构建根节点
TreeNode root = new TreeNode(Integer.parseInt(nodes[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int idx = 1;
while (!queue.isEmpty() && idx < nodes.length) {
TreeNode current = queue.poll();
// 构建左子节点
if (idx < nodes.length && !nodes[idx].equals("null")) {
current.left = new TreeNode(Integer.parseInt(nodes[idx]));
queue.offer(current.left);
}
idx++;
// 构建右子节点
if (idx < nodes.length && !nodes[idx].equals("null")) {
current.right = new TreeNode(Integer.parseInt(nodes[idx]));
queue.offer(current.right);
}
idx++;
}
return root;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] values = scanner.nextLine().split(" ");
Main main = new Main();
Solution solution = main.new Solution();
Solution.TreeNode tree = solution.buildTree(values);
System.out.println(solution.isSymmetric(tree));
}
}
C++ 递归实现
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
using namespace std;
// 二叉树节点定义
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
return isMirror(root->left, root->right);
}
private:
bool isMirror(TreeNode* left, TreeNode* right) {
if (!left && !right) return true;
if (!left || !right) return false;
return (left->val == right->val)
&& isMirror(left->left, right->right)
&& isMirror(left->right, right->left);
}
};
// 辅助函数:构造二叉树
TreeNode* buildTree(const vector<string>& nodes) {
if (nodes.empty() || nodes[0] == "null") {
return nullptr;
}
// 根节点
TreeNode* root = new TreeNode(stoi(nodes[0]));
queue<TreeNode*> q;
q.push(root);
int idx = 1;
while (!q.empty() && idx < (int)nodes.size()) {
TreeNode* current = q.front();
q.pop();
// 构建左子节点
if (idx < (int)nodes.size() && nodes[idx] != "null") {
current->left = new TreeNode(stoi(nodes[idx]));
q.push(current->left);
}
idx++;
// 构建右子节点
if (idx < (int)nodes.size() && nodes[idx] != "null") {
current->right = new TreeNode(stoi(nodes[idx]));
q.push(current->right);
}
idx++;
}
return root;
}
int main() {
string line;
getline(cin, line);
stringstream ss(line);
vector<string> values;
string val;
while (ss >> val) values.push_back(val);
Solution solution;
TreeNode* root = buildTree(values);
cout << (solution.isSymmetric(root) ? "true" : "false") << endl;
return 0;
}