20220223_datawhale34期_leetcode_5树

5 树

1.1 基础

树(Tree):由n >= 0个节点与节点之间的关系组成的有限集合。当 n = 0时称为空树,当n>0 时称为非空树。

  • 树是一种特殊的图 >>> 无环联通图

  • 可将树分为两种类型:「有序树」 和 「无序树」。

    有序树:节点的各个⼦树从左⾄右有序, 不能互换位置。
    无序树:节点的各个⼦树可互换位置。


  • 二叉树

二叉树(Binary Tree):树中各个节点的度不大于 2 个的有序树,称为二叉树。通常树中的分支节点被称为 「左子树」 或 「右子树」。二叉树的分支具有左右次序,不能随意互换位置(有序)。

满二叉树(Full Binary Tree):如果所有分支节点都存在左子树和右子树,并且所有叶子节点都在同一层上,则称该二叉树为满二叉树。

完全二叉树(Complete Binary Tree):如果叶子节点只能出现在最下面两层,并且最下层的叶子节点都依次排列在该层最左边的位置上(对应满二叉),具有这种特点的二叉树称为完全二叉树。

二叉搜索树(Binary Search Tree):也叫做二叉查找树、有序二叉树或者排序二叉树。是指一棵空树或者具有下列性质的二叉树

  • 如果任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值。
  • 如果任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值。
  • 任意节点的左子树、右子树均为二叉搜索树。

平衡二叉搜索树(Balanced Binary Tree):一种结构平衡的二叉搜索树。即叶节点高度差的绝对值不超过 1,并且左右两个子树都是一棵平衡二叉搜索树。平衡二叉树可以在 内完成插入、查找和删除操作。最早被发明的平衡二叉搜索树为 「AVL 树(Adelson-Velsky and Landis Tree))」。

1.2 题目

1.2.1 104 . 二叉树的最大深度

  • 1.DFS后序 >>> 左右 根(depth + 1)
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        # 后序dfs
        if not root:
            return 0
        ans = max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
        return ans
  • 2.DFS前序 >>> 根左右
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        # 先序dfs
        self.ans = 0
        depth = 0
        self.dfs(root, depth, self.ans)
        return self.ans
    def dfs(self, root, depth, ans):
        if not root:
            self.ans = max(self.ans, depth)
            return
        
        depth += 1
        self.dfs(root.left, depth, self.ans)
        self.dfs(root.right, depth, self.ans)
  • 3.BFS >>> 分层访问
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        depth,q = 0, collections.deque()
        q.append(root)
        while q:
            depth += 1
            for i in range(len(q)):
                temp = q.popleft()
                if temp.left:
                    q.append(temp.left)
                if temp.right:
                    q.append(temp.right)
        return depth

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

  • 思路: 利用二叉搜索树的中序遍历必然为一个有序序列性质 >> 以有序数组为中序 >>> 以中间元素为根节点并递归
class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        def bulidBST(l, r):
            if l > r:return
            mid = l + (r - l) // 2
            new_root = TreeNode(nums[mid])
            new_root.left = bulidBST(l, mid - 1)
            new_root.right = bulidBST(mid + 1, r)
            return new_root
        return bulidBST(0, len(nums) - 1)

1.2.3 111 . 二叉树的最小深度

1.DFS后序 >>>> 题目限制需要走到叶子节点 >>> 在最大深度基础上加条件即可

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root:return 0
        l, r = self.minDepth(root.left), self.minDepth(root.right)  #加快运算效率
        if not l:return r + 1    #左无子看右
        if not r:return l + 1    #右无子看左
        return min(l, r) + 1

2.BFS >>> 增加到叶子返回深度条件即可

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root:return 0
        depth, q = 0, collections.deque()
        q.append(root)
        while q:
            depth += 1
            for i in range(len(q)):
                cur = q.popleft()
                if not cur.left and not cur.right:  #到叶子
                    return depth
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
        return depth

1.2.4 112 . 路径总和

  • 思路:
    1.DFS >>> 利用target -root.val遍历左右子树, 查找到根节点最后是否存在target == root.val
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
            if not root:return False #边界1
            if not root.left and not root.right: #边界2 确定到根节点
                return root.val == targetSum
            return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum(root.right, targetSum - root.val)

2.BFS

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:return False
        q = collections.deque()
        q.append((root, root.val))
        while q:
            cur, target = q.popleft()
            if not cur.left and not cur.right and target == targetSum:
                return True
            if cur.left:
                q.append((cur.left, cur.left.val + target))
            if cur.right:
                q.append((cur.right, cur.right.val + target))
        return False

1.2.5 173 . 二叉搜索树迭代器

  • 思路: 利用中序性质即可
class BSTIterator:

    def __init__(self, root: TreeNode):
        self.stack = []
        self.index = -1
        def Inorder(root):
            if root:
                Inorder(root.left)
                self.stack.append(root.val)
                Inorder(root.right)
        Inorder(root)


    def next(self) -> int:
        self.index += 1
        return self.stack[self.index]


    def hasNext(self) -> bool:
        return len(self.stack) - 1 > self.index
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值