可视化图解算法28:对称的二叉树(判断二叉树是否为对称的)

85 阅读3分钟

1. 题目

描述

给定一棵二叉树,判断其是否是自身的镜像(即:是否对称) 例如: 下面这棵二叉树是对称的

BM31_1.png

下面这棵二叉树不对称。

BM31_2.png

数据范围:节点数满足 0≤n≤1000,节点上的值满足∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

备注:

你可以用递归和迭代两种方法解决这个问题

示例1

输入:

{1,2,2,3,4,4,3}

返回值:

true

示例2

输入:

{1,2,2,#,3,#,3}

返回值:

false

示例3

输入:

{8,6,9,5,7,7,5}

返回值:

false

2. 解题思路

判断一颗二叉树是否对称可以采用以下方法:

  1. 将二叉树复制一份

  2. 对2颗二叉树进行比较(采用递归方法)

​ 树1的左子树与树2的右子树进行比较;

​ 树1的右子树与树1的左子树进行比较;

​ 当比较结果都为true时,二叉树为对称的二叉树。

假如要判断的二叉树结构如下图所示:

28-01.png

这样一颗二叉树进行复制,会变成两颗完全一样的二叉树:

28-02.png

先来看看该二叉树是否可以通过递归来判断对称性。

28-1.png

28-2.png

递归的两个条件满足,因此可以通过递归来判断二叉树是否为对称。

对于这两颗二叉树来说,先判断两颗二叉树的节点值是否相等(root1.val是否等于root2.val);再用树1的左子树与树2的右子树进行比较,用树1的右子树与树1的左子树进行比较。因此对应的递推公式如下所示:

28-4.png

有了递推公式,就可以方便的写出对应的代码了。

如果文字描述的不太清楚,你可以参考视频的详细讲解。

3. 编码实现

核心代码如下:

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * @param pRoot TreeNode类
 * @return bool布尔型
 */
func isSymmetrical(pRoot *TreeNode) bool {
	// write code here
	return recursion(pRoot, pRoot)
}

func recursion(root1 *TreeNode, root2 *TreeNode) bool {
	// 2. 递归终止条件
	// 2.1 递归条件:两个节点都为空,为true
	if root1 == nil && root2 == nil {
		return true
	}
	// 2.2 只有一个节点为空,必定不对称
	if (root1 == nil && root2 != nil) || (root1 != nil && root2 == nil) {
		return false
	}

	// 1. 问题分解(递推公式)
	return (root1.Val == root2.Val) && recursion(root1.Left, root2.Right) && recursion(root1.Right, root2.Left)
}

具体完整代码你可以参考下面视频的详细讲解。

4.小结

判断二叉树是否为对称,可以采用以下方法:将二叉树复制一份;对2颗二叉树进行比较(采用递归方法),树1的左子树与树2的右子树进行比较,树1的右子树与树1的左子树进行比较,当比较结果都为true时,二叉树为对称的二叉树。

分割线.png

《数据结构与算法》深度精讲课程正式上线啦!七大核心算法模块全解析:

✅ 链表 ✅ 二叉树 ✅二分查找、排序 ✅ 堆、栈、队列 ✅回溯算法 ✅ 哈希算法 ✅ 动态规划

无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!

对于二叉树的相关算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:不似春光,胜似春光,寥廓江天万里霜。