解法一:基于分解子问题思维模式的递归
如果同时满足下面的条件,两个树互为镜像:
- 它们的两个根结点具有相同的值
- 每个树的右子树都与另一个树的左子树镜像对称
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
if root == nil{
return true
}
return isMirror(root.Left, root.Right)
}
// isMirror: 判断两棵子树是否镜像对称
func isMirror(left, right *TreeNode) bool{
// 判断左右子节点是否对称
if left == nil && right == nil{
return true
}else if left == nil || right == nil{
return false
}else if left.Val != right.Val{
return false
}
// 左右子节点值相等了,还得再看二者的子树是否对称
return isMirror(left.Left, right.Right) && isMirror(left.Right, right.Left)
}
解法二:基于遍历思维模式的递归
这题比较特殊,为了判断左右子树是否对称,必须每次都是同时遍历左右子节点,不能写成之前的框架
func traverse(root *TreeNode) {
if root == nil { return }
traverse(root.Left)
traverse(root.Right)
}
得适当变种一下,但是整体思路不变,仍为遍历中不断更新答案
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
if root == nil{
return true
}
res := true // 先假设为 true
traverse(root.Left, root.Right, &res)
return res
}
func traverse(left, right *TreeNode, isMirror *bool){
if left == nil && right == nil{ // 遍历到叶子节点了,递归退出条件
return
}else if left == nil || right == nil || left.Val != right.Val{
*isMirror = false // 中途不对称立即返回答案
return
}
// 递归遍历两个节点的子树
traverse(left.Left, right.Right, isMirror)
traverse(left.Right, right.Left, isMirror)
}