DAY14 二叉树part2

226. 翻转二叉树

简单

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

方法一:递归(前/后) 

递归三部曲:

  1. 传入参数和返回值:无需参数、返回根节点root
  2. 终止条件:当前节点为空的时候,就返回
    if root == NULL: return root
  3. 确定单层递归的逻辑:

    前序遍历,先交换左右孩子节点,然后反转左子树,反转右子树。若是后序遍历(左右中),交换顺序即可。

    # 前序遍历
    root.left, root.right = root.right, root.left #中
    self.invertTree(root.left) #左
    self.invertTree(root.right)#右
    
    # 后序遍历
    self.invertTree(root.left) #左
    self.invertTree(root.right)#右
    root.left, root.right = root.right, root.left #中
    

不可以中序遍历的原因:会重复处理左子树

解决方法:

单层代码逻辑里,左中后再次左

self.invertTree(root.left) # 左
root.left, root.right = root.right, root.left # 中
self.invertTree(root.left) # 左

前序遍历 

# 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 not root:
            return None
        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:
#     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 not root:
            return None
        self.invertTree(root.left)
        self.invertTree(root.right)
        root.left, root.right = root.right, root.left
        return root

中序遍历

# 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 not root:
            return None
        self.invertTree(root.left)
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        return root

方法二:迭代

深度优先遍历(前中后):栈

广度优先遍历(层序遍历):队列

 前序遍历

# 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 not root:
            return None      
        stack = [root]        
        while stack:
            node = stack.pop()   
            node.left, node.right = node.right, node.left                   
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)  
        return root

后序遍历

# 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 not root:
            return None      
        stack = [root]        
        while stack:
            node = stack.pop()                   
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)  
            node.left, node.right = node.right, node.left               
     
        return root

中序遍历

# 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 not root:
            return None      
        stack = [root]        
        while stack:
            node = stack.pop()                   
            if node.left:
                stack.append(node.left)
            node.left, node.right = node.right, node.left               
            if node.left:
                stack.append(node.left)       
        return root

层序遍历

# 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 not root: 
            return None

        queue = collections.deque([root])    
        while queue:
            for i in range(len(queue)):
                node = queue.popleft()
                node.left, node.right = node.right, node.left
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
        return root   

101. 对称二叉树

简单

给你一个二叉树的根节点 root , 检查它是否轴对称。

方法一:递归(后序)

注意点1:比较的是什么,要比较的可不是左右节点!

        其实要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

        比较的是两个子树的里侧和外侧的元素是否相等

注意点2:遍历顺序

要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

所以只能后序遍历

注意点3:判断空节点     若p和q有至少一个节点为空,判断p is q

  1. p、q 其中有一个是none,判断p、q是否为同一对象
  2. p、q都为空,p is q为true

        则接下来的情况为p、q都不为空

# 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 isSame(self, p:Optional[TreeNode], q:Optional[TreeNode])->bool:
        if p is None or q is None:
            return p is q
        return p.val == q.val and self.isSame(p.left,q.right) and self.isSame(q.left,p.right)
    def isSymmetric(self,root:Optional[TreeNode]):
        return self.isSame(root.left,root.right)

方法二:迭代(层序)

使用队列,加入一层的节点,层序遍历,每次弹出两个节点进行比较(按照代码顺序是先外侧后内侧)

比较逻辑:

  • 若都为空,continue跳出迭代,继续比较另外两个节点
  • 一个为空一个不为空:false
  • 都不为空,但值不相同:false

使用栈也可以

# 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
        queue = deque()
        queue.append(root.left)
        queue.append(root.right)
        while queue:
            leftnode = queue.popleft()
            rightnode = queue.popleft()
            # if not leftnode or not rightnode:
            #    return leftnode is rightnode
            # 这样判断当有一个为空时逻辑正确,但都为空时就直接返回true,应该继续比较
            if not leftnode and not rightnode:
                continue
            # 只有一个为空,不对称
            if not leftnode or not rightnode:
                return False
            # 值不相等,不对称
            if leftnode.val != rightnode.val:
                return False
            queue.append(leftnode.left)
            queue.append(rightnode.right)
            queue.append(leftnode.right)
            queue.append(rightnode.left)
        return True

 104. 二叉树的最大深度

简单

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

方法一:递归(后序求高度)

根节点的高度就是二叉树的最大深度,通过后序求的根节点高度来求的二叉树最大深度。

高度:从下往上----后序遍历

深度:从上往下----前序遍历

递归三部曲:

  1. 确定参数和返回值:参数为要传入的二叉树根节点,返回的是int类型的深度。
  2. 终止条件:if not root: return 0 表示当前节点的高度为0
  3. 单层递归的逻辑:后序求高度 左右中
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        l_depth= self.maxDepth(root.left) # 左
        r_depth = self.maxDepth(root.right) # 右
        height = max(l_depth,r_depth) +1 # 中
        return height

方法二:迭代(层序-队列)


class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        q = deque([root])
        ans = 0
        while q:
            for _ in range(len(q)): #如果没有这句每次只让当层的一个节点出队,进行下一个循环,ans值偏高。
                node = q.popleft()
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            ans+=1
        return ans

111. 二叉树的最小深度

简单

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

 

方法一:递归(后序)

递归三部曲:

  1. 确定参数和返回值:参数为要传入的二叉树根节点,返回的是int类型的深度。
  2. 终止条件:if not root: return 0 表示当前节点的高度为0
  3. 单层递归的逻辑:后序求高度 左右中

仿照最大深度可以写出如下代码:

leftDepth = self.getDepth(node.left)  # 左
rightDepth = self.getDepth(node.right)  # 右
result = 1 + min(leftDepth, rightDepth) #中

错误的原因:左右孩子都为空的节点才是叶子节点!如果这么求的话,没有左孩子的分支会算为最短深度。

修改:增加判断

  • 如果左子树为空,返回右子树最小高度+1
  • 如果右子树为空,返回左子树最小高度+1
  • 如果左右都不空,返回左右子树深度最小值 + 1 。

# 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
        if root is None:
            return 0
        if root.left is None:
            return self.minDepth(root.right)+1
        if root.right is None:
            return self.minDepth(root.left)+1

        l_depth = self.minDepth(root.left)
        r_depth = self.minDepth(root.right)
        return min(l_depth,r_depth)+1

        # return min(l_depth,r_depth)+1 if min(l_depth,r_depth)+1!=1 else max(l_depth,r_depth)+1

方法二:迭代 (层序)

class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        q = deque([root])
        ans = 1
        while q:
            for _ in range(len(q)):
                node = q.popleft()
                if node.left is None and node.right is None:
                    return ans
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            ans+=1
       

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值