***【LeetCode 101】对称二叉树(Python)

一、题目

给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值