一、题目
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
二、解题思路(递归)
拿到这道题后我的思路是:首先按层走,然后在每层内正反两个顺序同步遍历,判断是否相同。如果相同,说明对称,是镜像。
我没有用leetcode内提供的模板去写,因为我一直对TreeNode运用的不大好。不太会调用左右子树。所以我把二叉树看成一个列表去做,但思路都是一样的,所以放出来做个参考。等我之后想好怎么用左右节点去实现再补充。
1.分层:每层开头的索引位置是2**int((len(列表)-2)**0.5)-1,用第一个图举例:每层开头索引是0,1,3,但因为我的运算是开平方,所以层是按倒序排的3,1,0 (得到了每层开头的索引)结尾的索引就简单了,下一层的开头索引减1就是。
2.每层内正序和倒序同步进行,判断是否相同。(因为第一层也就是根节点只有一个数,肯定对称,所以不在考虑范围内)
3.代码:我当时忘了写为空的情况判断,以后再补吧。
优点:思路清晰,不绕不复杂。时间复杂度和空间复杂度都不高。而且可以很明显的看出是哪里不对称。
缺点:不适用于leetcode中二叉树的定义,无法提交。涉及到的公式不太好理解(对于我自己当然好理解,意思是我给别人讲不出来)。
class Solution:
def res(self,a,list_a):
if a>=0:
print("a=",a)
b=2**int(a**0.5)
print("b=",b)
new_b=b-1
new_a=a+1
while new_b<new_a:
if list_a[new_b]==list_a[new_a]:
print("对称:第",new_b,"和第",new_a)
else: print("不对称:第",new_b,"和第",new_a)
new_b+=1
new_a-=1
a=a-b
self.res(a,list_a)
s=Solution()
list_a=[1,2,2,3,5,5,3,4,6,4,6,6,4,88,4] #例1:不对称
a=len(list_a)-2
s.res(a,list_a)
# 13,[1,2,2,3,4,4,3,5,6,6,5,5,6,6,5]
# 5,[1,2,2,3,4,4,3] #例2:对称
4.例1运行结果展示:(不对称的情况,最后一层从外向内数第二对)
4.例2运行结果展示:(对称的情况)
三、学习别人的方法
在leetcode解析里看到一位网友提出的方法很新颖好用,所以放到这里供自己学习。
现有一棵树是对称二叉树:
首先我们对这棵树根节点的左子树进行前序遍历: pre_order = [2,3,5,6,4,7,8]
接着我们对这棵树根节点的右子树进行后序遍历:post_order = [8,7,4,6,5,3,2]
根据两次遍历我们不难发现 post_order 就是 pre_order的逆序,其实这也是对称二叉树的一个性质,根据这一点就不难写出代码了。
作者:han-han-a-gou
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/python3-yi-ge-hao-li-jie-de-shen-qi-jie-fa-by-han-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
bli = [] # 用来存左子树的前序遍历
fli = [] # 用来存右子树的后序遍历
if root == None: # 无根节点
return True
if root and root.left == None and root.right == None: # 只有根节点
return True
if root and root.left and root.right:
self.pre_order(root.left, bli)
self.post_order(root.right, fli)
fli.reverse() # 将后序遍历的列表倒序
if bli == fli:
return True
else:
return False
def pre_order(self,root,li): # 二叉树的前序遍历
if root:
li.append(root.val)
self.pre_order(root.left,li)
self.pre_order(root.right,li)
elif root == None:
li.append(None)
def post_order(self,root,li): # 二叉树的后序遍历
if root:
self.post_order(root.left,li)
self.post_order(root.right,li)
li.append(root.val)
elif root == None:
li.append(None)
作者:han-han-a-gou
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/python3-yi-ge-hao-li-jie-de-shen-qi-jie-fa-by-han-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
四、leetcode上大部分人用的方法(必须看会,属于常规写法)
https://leetcode-cn.com/problems/symmetric-tree/solution/dong-hua-yan-shi-101-dui-cheng-er-cha-shu-by-user7/