求二叉树的属性-对称/翻转

226. 翻转二叉树

在这里插入图片描述

翻转过程:
交换左右孩子在这里插入图片描述
在这里插入图片描述
**前序遍历(深度优先) **

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if root == None: return  
        root.left,root.right = root.right,root.left #中
        self.invertTree(root.left)# 左
        self.invertTree(root.right)# 右
        return root

层次遍历(广度优先)

 # Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        
        if not root:
            return root
        que = deque([root])
        while que:
            size = len(que)
            for _ in range(size):
                cur = que.popleft()
                #交换左右孩子
                cur.left,cur.right =  cur.right,cur.left
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
        return root

589. N 叉树的前序遍历

在这里插入图片描述
递归法

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution(object):
    def preorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """
        r = []

        def travelsal(root):
            if not root:
                return
            r.append(root.val)
            for child in root.children:
                travelsal(child)

        travelsal(root)
        return r

迭代法

"""
# Definition for a Node.
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        # 参考二叉树 前序遍历 中左右 中pop 入栈是右左
        # 所以中pop 入栈 孩子们逆序入栈

        if not root:
            return []
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            res.append(node.val)# 中
            stack.extend(node.children[::-1])# 孩子逆序入栈
        return res


590. N 叉树的后序遍历

在这里插入图片描述
递归法

"""
# Definition for a Node.
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution:
    def postorder(self, root: 'Node') -> List[int]:
        r = []
        def travelsal(root):
            if not root:
                return
            #参考二叉树后序 左右中
            for child in root.children:
                travelsal(child)
            r.append(root.val)
            
        travelsal(root)
        return r 

            

迭代法

 """
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution(object):
    def postorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """

        # 参考二叉树 后序遍历 左右中
        # 前序是中左右 所以左右互换 变中右左 再逆转 变左右中 即后序
        # 所以中pop 入栈是左右 出栈才是右左 所以孩子们顺序入栈

        if not root:
            return []
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            res.append(node.val)# 中
            stack.extend(node.children)# 孩子逆序入栈
        return res[::-1]

101. 对称二叉树

在这里插入图片描述
要比较的是根节点的左子树与右子树是不是相互翻转的
思路:
1.怎么判断一棵树是不是对称二叉树? 答案:如果所给根节点,为空,那么是对称。如果不为空的话,当他的左子树与右子树对称时,他对称

2.那么怎么知道左子树与右子树对不对称呢?答案:如果左树的左孩子与右树的右孩子对称,左树的右孩子与右树的左孩子对称,那么这个左树和右树就对称。
在这里插入图片描述

仔细读这句话,是不是有点绕?怎么感觉有一个功能A我想实现,但我去实现A的时候又要用到A实现后的功能呢?

当你思考到这里的时候,递归点已经出现了: 递归点:我在尝试判断左树与右树对称的条件时,发现其跟两树的孩子的对称情况有关系。

想到这里,你不必有太多疑问,上手去按思路写代码,函数A(左树,右树)功能是返回是否对称

def 函数A(左树,右树): 左树节点值等于右树节点值 且 函数A(左树的左子树,右树的右子树),函数A(左树的右子树,右树的左子树)均为真 才返回真

具体递归思路根据三要素确定:

  • 1确定递归函数的参数和返回值
    比较的是两个树,参数自然也是左子树节点和右子树节点,返回值自然是bool类型。
  • 2确定终止条件
    左右都不空,比较val,不同false
    左空右不空,false,左不空右空,false
    左右都空,true
  • 3确定单层递归的逻辑
    比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
    比较内测是否对称,传入左节点的右孩子,右节点的左孩子。
    如果左右都对称就返回true ,有一侧不对称就返回false 。

递归法

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        def compare(left,right):
            # 边界出口
            if left == None and right != None: return False
            elif left != None and right == None: return False
            elif left == None and right == None: return True
            #排除了空节点,再排除数值不相同的情况
            elif left.val != right.val: return False

            # 单层逻辑 1比较,左的左,右的右 2比较,左的右,右的左
            # 只有都成立 才是对称
            res = compare(left.left,right.right) and compare(left.right,right.left)
            return res
        
        # 空树是对称的
        if not root:
            return True
        return compare(root.left,root.right)



迭代法
在这里插入图片描述

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        que = deque()
        # 将左、右子树头结点加入队列
        que.append(root.left)
        que.append(root.right)

        while que:
            # 判断是否可以翻转
            left = que.popleft()
            right = que.popleft()
            # 判断边界条件

            # 左右都空 对称
            if not left and not right:
                continue
            # 左右结点有一个不空,或都不空但是值不同,不对称
            if not left or not right or left.val != right.val:
                return False
            
            # 说明目前是对称的 添加到队列
            que.append(left.left) #加入左节点左孩子
            que.append(right.right) #加入右节点右孩子
            que.append(left.right) #加入左节点右孩子
            que.append(right.left) #加入右节点左孩子.
            
        return True



100.相同的树

在这里插入图片描述
在这里插入图片描述

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:

        # 1比较左树的左、右树的左,2左树的右、右树的右, 1、2同时为真才是完全相同的
        def compare(leftTree,rightTree):
            # 边界
            if not leftTree and not rightTree:return True
            elif not leftTree or not rightTree or leftTree.val != rightTree.val:return False
        
            # 单层逻辑
            res = compare(leftTree.left, rightTree.left) and compare(leftTree.right, rightTree.right)
            return res

        if not p and not q:
            return True
        return compare(p, q)


            

572.另一个树的子树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:

        # compare函数 是判断是否是一棵树
        # 1比较左树的左、右树的左,2左树的右、右树的右, 1、2同时为真才是完全相同的一棵树
        def compare(leftTree,rightTree):
            # 边界
            if not leftTree and not rightTree:return True
            elif not leftTree or not rightTree or leftTree.val != rightTree.val:return False
        
            # 单层逻辑
            res = compare(leftTree.left, rightTree.left) and compare(leftTree.right, rightTree.right)
            return res
       

        # root要么等于sub,root的左子树等于sub,root的右子树等于sub。这三种情况返回true 
        
        if not root and not subRoot:# 都为空时,相同符合
            return True
        if not root or not subRoot:# 有一个为空,则不符合
            return False
        # 注意后面两个条件是是否是子树的条件
        ans = compare(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
        return ans
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值