题目描述
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
思路
递归
- 如果当前节点为null,那么不存在左右子树不对称的情况,返回true
- 如果左右子树一个为null另一个不为null,不对称,返回false
- 如果左右子树都为null,对称,返回true
- 如果左子树的左节点与右子树的右节点,或者左子树的右节点与右子树的左节点值不同,返回false
- 对根节点的左右子树进行递归
循环
- 初始化队列:
- 将根节点的左子节点和右子节点分别加入队列。
- 循环遍历:
- 使用
while循环直到队列为空。 - 每次从队列中取出两个节点进行比较。
- 如果两个节点都为空,则继续下一次循环。
- 如果其中一个节点为空或节点值不相等,则返回
false。 - 否则,将这两个节点的子节点按照对称顺序加入队列。
- 使用
- 结束条件:
- 如果队列为空,说明所有节点都满足对称条件,返回
true。
- 如果队列为空,说明所有节点都满足对称条件,返回
复杂度分析
时间复杂度
- 递归:
- 时间复杂度:O(n),其中 n 是二叉树的节点数。每个节点都被访问一次。
- 原因:递归方法通过递归调用
isMirror函数来比较每个节点的左右子树,每个节点都被访问一次。
- 循环:
- 时间复杂度:O(n),其中 n 是二叉树的节点数。每个节点都被访问一次。
- 原因:循环方法通过队列来逐层比较节点,每个节点也被访问一次。
空间复杂度
- 递归:
- 空间复杂度:O(h),其中 h 是二叉树的高度。
- 原因:递归方法使用了系统栈来存储递归调用,最坏情况下(完全不平衡的树),空间复杂度为 O(n);平均情况下(平衡树),空间复杂度为 O(log n)。
- 循环:
- 空间复杂度:O(n),其中 n 是二叉树的节点数。
- 原因:循环方法使用了一个队列来存储节点,最坏情况下(完全平衡的树),队列中可能会存储所有的叶子节点,因此空间复杂度为 O(n)。
code
递归
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(!root) return true
return isMirror(root.left) && isMirror(root.right)
}
function isMirror(left, right) {
if (!left && !right) return true; // 两个节点都为空
if (!left || !right) return false; // 一个节点为空,另一个不为空
if (left.val !== right.val) return false; // 节点值不相等
// 递归检查左子树的左子节点与右子树的右子节点,以及左子树的右子节点与右子树的左子节点
return isMirror(left.left, right.right) && isMirror(left.right, right.left);
};
循环
var isSymmetric = function(root) {
if(!root) return true
const queue = []
queue.push(root.left)
queue.push(root.right)
while(queue.length > 0){
let left = queue.shift()
let right = queue.shift()
if(!left && !right) continue
if(!left || !right) return false
if(left.val !== right.val) return false
queue.push(left.left)
queue.push(right.right)
queue.push(left.right)
queue.push(right.left)
}
return true
}