Leetcode | 以二叉树,多叉树为主题的理论,真题以及图解【更新中】

1.理论

1.1.二叉树

1.1.1.二叉树的遍历

前序(preorder traversal):从根节点开始,先访问当前节点,然后递归地遍历左子树,最后递归地遍历右子树。即“根-左-右”的顺序。

中序遍历(inorder traversal):从根节点开始,先递归地遍历左子树,然后访问当前节点,最后递归地遍历右子树。即“左-根-右”的顺序。

后序遍历(postorder traversal):从根节点开始,先递归地遍历左子树,然后递归地遍历右子树,最后访问当前节点。即“左-右-根”的顺序。

层序遍历(level-order traversal):从根节点开始,按照树的层次顺序,从上到下、从左到右依次访问节点。

遍历顺序: 12345

1.1.2.树的路径和(path sum in binary trees)

树的路径和指的是从树的根节点到叶子节点的路径上所有节点值的和。通常问题会要求找出是否存在这样的路径,或者找出所有满足条件的路径。解决这类问题通常需要使用深度优先搜索(DFS)或广度优先搜索(BFS)等方法。

1.1.3.二叉查找树(binary search trees(BST)

 二叉查找树是一种二叉树,其中每个节点的值大于其左子树中的所有节点的值,小于其右子树中的所有节点的值。这种特性使得在BST中进行搜索、插入和删除等操作具有较高的效率。通常,中序遍历BST会得到一个有序的序列。

特性:

  • 左子树中的所有节点的键值小于根节点的键值
  • 右子树中的所有节点的键值大于根节点的键值
  • 左子树和右子树也都是二叉搜索树

1.1.4.二叉树转换

二叉树转换指的是将一个二叉树转换为另一个形式的操作。例如,可以将一个有序数组转换为平衡的二叉搜索树,或者将一个二叉搜索树转换为双向链表等。这类问题常常需要根据特定的转换规则来进行设计和实现。

1.2.多叉树遍历

多叉树是一种每个节点可以有多个子节点的树结构。多叉树的遍历方式与二叉树类似,也包括前序、中序、后序和层序遍历。在多叉树中,每个节点的子节点数目不固定,因此在遍历时需要考虑如何处理不同数量的子节点。

真题

简单

94.二叉树的中序遍历

题目:给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

方法:递归方解法

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

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result=[]
        if root is None:
            return result
        result +=self.inorderTraversal(root.left)
        result.append(root.val)
        result +=self.inorderTraversal(root.right)
        return result

101.对称二叉树

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

题目分析:首先需要检查根节点是否为空,如果为空,返回True,就被认为是对称的。再确定俩边是否为镜像对称,俩个节点都为空被认为是对称的,在比较左右的节点值,如果相同,则返回True,否则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
        return self.ismrrior(root.left,root.right)

    def ismrrior(self,left:TreeNode,right:TreeNode) -> bool:
        if not left and not right:
            return True
        if not left or not right or left.val != right.val:
            return False
        return self.ismrrior(left.left,right.right) or self.ismrrior(left.right,right.left)
        

104.二叉树的最大深度

108.将有序数组转换为二叉搜索树

226.翻转二叉树

543.二叉树的直径

590.N叉树的后序遍历

给定一个 n 叉树的根节点 root ,返回 其节点值的 后序遍历 。

n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔

中等

98.验证二叉搜索树

题目:

题目分析:在验证二叉搜索树时,要明确二叉搜索树的特征,假设节点的最小值和最大值,日过当前节点的值小于最小值 或者 大于最大值时,返回为假。当左子树都小于根节点,右子树都大于根节点时,返回为真,确认此树为二叉搜索树!

# 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 isValidBST(self, root:TreeNode,min_val=float('-inf'),max_val=float('inf')) -> bool:
        if root is None:
            return True
        if root.val<=min_val or root.val>=max_val:
            return False
        return (self.isValidBST(root.left,min_val,root.val) and self.isValidBST(root.right,root.val,max_val))
        

102.二叉树的层序遍历

困难

124.二叉树中的最大路径和(Binary Tree Maximum Path Sum)

题目:给定一个二叉树,返回最大路径之和

Given the root of a binary tree, return the maximum path sum of any non-empty path.

 题目分析:求出左子树、右子树的最大值,将最大值相加。

# 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 maxPathSum(self, root: Optional[TreeNode]) -> int:
        self.max_sum=float('-inf')
        def max_path_sum(node):
            if node is None:
                return 0
            left_sum=max(0,max_path_sum(node.left))
            right_sum=max(0,max_path_sum(node.right))
            self.max_sum=max(self.max_sum,left_sum+right_sum+node.val)
            return max(left_sum,right_sum)+node.val

        max_path_sum(root)
        return self.max_sum

 代码解释:

  • 创建MaxPathSum 的方法,接收一个二叉树的根节点作为输入,初始化一个变量max_sum为负无穷,用来存储最大路径和的值
  • 再定义一个max_path_sum的辅助函数,用来处理特殊情况,假如节点为空时,返回0.再分别计算左子树和右子树的最大路径和,分别将他们存储在left/right_sum中。
  • 更新max_sum的值,取当前最大路径和左右子树路径和的和,在加上节点值的最大值
  • 最后返回当前节点为根的最大路径和,是左右子树路径和中较大的值再加上当前节点的值。
  • 调用max_path_sum函数,从根节点递归计算最大路径和
  • 最终但会max_sum,整棵树的最大路径和

--》单独计算左子树和右子树是为了确定这些路径是连续的

--》node.val 在递归过程中会被更新为当前节点的值,以确保在计算每个子树的最大路径和时都考虑了当前节点的值。

参考文献

【1】LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

【2】Inorder Traversal of Binary Tree - GeeksforGeeks 

【3】Inorder Tree Traversal – Iterative and Recursive | Techie Delight 

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天|여름이다

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值