代码随想录算法训练营第十四天|LC226.翻转二叉树|LC101.对称二叉树|LC104.二叉树的最大深度|LC111.二叉树的最小深度

226. 翻转二叉树 - 力扣(LeetCode)

        思路:将节点的左右子树进行翻转即可

        使用前序遍历或者后序遍历,这两者可以把根节点定下来,但是中序遍历的话会把第二层的节点再次交换(可以画图知)

        迭代法:

from typing import List, Optional
from collections import deque
# 二叉树生成代码
def generate_tree(vals):
    if len(vals) == 0:
        return None
    que = [] # 定义队列
    fill_left = True # 由于无法通过是否为 None 来判断该节点的左子树是否可以填充,用一个记号判断是否需要填充左节点
    for val in vals:
        node = TreeNode(val) if val else None # 非空值返回节点类,否则返回 None
        if len(que)==0:
            root = node # 队列为空的话,用 root 记录根结点,用来返回
            que.append(node)
        elif fill_left:
            que[0].left = node
            fill_left = False # 填充过左子树后,改变记号状态
            if node: # 非 None 值才进入队列
                que.append(node)
        else:
            que[0].right = node
            if node:
                que.append(node)
            que.pop(0) # 填充完右子树,弹出节点
            fill_left = True #
    return root

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: Optional[TreeNode]) -> Optional[TreeNode]:
        # 前序遍历
        if not root:
            return None
        # 先将根节点的左右子树进行对换
        root.left, root.right = root.right, root.left
        # 对左子树节点进行兑换
        self.invertTree(root.left)
        # 对右子树节点进行兑换
        self.invertTree(root.right)
        return root


if __name__ == '__main__':
    null = None
    root = [4,2,7,1,3,6,9]
    root = generate_tree(root)
    res = Solution().invertTree(root)
    print(res.val)
    print(res.left.val)
    print(res.right.val)
    print(res.left.left.val)
    print(res.left.right.val)
    print(res.right.left.val)
    print(res.right.right.val)

101. 对称二叉树 - 力扣(LeetCode)

思路:要比较的是节点下的左右子树能否互相翻转,若可以,则是对称,若不行,则不对称;

        本题遍历只能是“后序遍历”:因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

from typing import List, Optional
from collections import deque
# 二叉树生成代码
def generate_tree(vals):
    if len(vals) == 0:
        return None
    que = [] # 定义队列
    fill_left = True # 由于无法通过是否为 None 来判断该节点的左子树是否可以填充,用一个记号判断是否需要填充左节点
    for val in vals:
        node = TreeNode(val) if val else None # 非空值返回节点类,否则返回 None
        if len(que)==0:
            root = node # 队列为空的话,用 root 记录根结点,用来返回
            que.append(node)
        elif fill_left:
            que[0].left = node
            fill_left = False # 填充过左子树后,改变记号状态
            if node: # 非 None 值才进入队列
                que.append(node)
        else:
            que[0].right = node
            if node:
                que.append(node)
            que.pop(0) # 填充完右子树,弹出节点
            fill_left = True #
    return root

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
        return self.compare(root.left, root.right)

    def compare(self, left, right):
        # 排除空节点的情况
        if left == None and right == None:
            # 两个一个剩右,一个剩左,对称
            return True
        elif left != None and right == None:
            return False
        elif left == None and right != None:
            return False
        # 排除左右节点值不一致的情况
        elif left.val != right.val:
            return False
        # 左右节点都部位空,可以进行递归做下一层判断
        outside = self.compare(left.left, right.right) # 左子树:左、右子树:右
        inside = self.compare(left.right, right.left) # # 左子树:右、右子树:左
        isSame = outside and inside
        return isSame


if __name__ == '__main__':
    null = None
    root = [1,2,2,3,4,4,3]
    root = generate_tree(root)
    res = Solution().isSymmetric(root)
    print(res)

104. 二叉树的最大深度 - 力扣(LeetCode)

from typing import List, Optional
from collections import deque
# 二叉树生成代码
def generate_tree(vals):
    if len(vals) == 0:
        return None
    que = [] # 定义队列
    fill_left = True # 由于无法通过是否为 None 来判断该节点的左子树是否可以填充,用一个记号判断是否需要填充左节点
    for val in vals:
        node = TreeNode(val) if val else None # 非空值返回节点类,否则返回 None
        if len(que)==0:
            root = node # 队列为空的话,用 root 记录根结点,用来返回
            que.append(node)
        elif fill_left:
            que[0].left = node
            fill_left = False # 填充过左子树后,改变记号状态
            if node: # 非 None 值才进入队列
                que.append(node)
        else:
            que[0].right = node
            if node:
                que.append(node)
            que.pop(0) # 填充完右子树,弹出节点
            fill_left = True #
    return root

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:
        return self.getdepth(root)

    def getdepth(self, node):
        if not node:
            return 0
        # 计算左侧深度
        leftheight = self.getdepth(node.left)
        # 计算右侧深度
        rightheight = self.getdepth(node.right)
        # 加1是因为深度是从1开始的
        height = 1 + max(leftheight, rightheight)
        return height
    
    
if __name__ == '__main__':
    null = None
    root = [3,9,20,null,null,15,7]
    root = generate_tree(root)
    res = Solution().maxDepth(root)
    print(res)

111. 二叉树的最小深度 - 力扣(LeetCode)

         前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度

        特别注意:当一个左子树为空,右子树不为空时,最低点并不是左子树的位置,而是要根据右子树来判断,翻转同理;

from typing import List, Optional
from collections import deque
# 二叉树生成代码
def generate_tree(vals):
    if len(vals) == 0:
        return None
    que = [] # 定义队列
    fill_left = True # 由于无法通过是否为 None 来判断该节点的左子树是否可以填充,用一个记号判断是否需要填充左节点
    for val in vals:
        node = TreeNode(val) if val else None # 非空值返回节点类,否则返回 None
        if len(que)==0:
            root = node # 队列为空的话,用 root 记录根结点,用来返回
            que.append(node)
        elif fill_left:
            que[0].left = node
            fill_left = False # 填充过左子树后,改变记号状态
            if node: # 非 None 值才进入队列
                que.append(node)
        else:
            que[0].right = node
            if node:
                que.append(node)
            que.pop(0) # 填充完右子树,弹出节点
            fill_left = True #
    return root

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        return self.getDepth(root)

    def getDepth(self, node):
        if not node:
            return 0
        # 计算左侧深度
        leftDepth = self.getDepth(node.left)
        # 计算右侧深度
        rightDepth = self.getDepth(node.right)
        # 当一个左子树为空,右子树不为空,这时最低点并不是左子树的位置
        if node.left is None and node.right is not None:
            return 1+rightDepth
        # 当一个右子树为空,左子树不为空,这时最低点并不是右子树的位置
        if node.left is not None and node.right is None:
            return 1+leftDepth

        res = 1+min(leftDepth, rightDepth)
        return res


if __name__ == '__main__':
    null = None
    root = [3,9,20,null,null,15,7]
    root = generate_tree(root)
    res = Solution().minDepth(root)
    print(res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值