作业3(五十道)

437.路径总和Ⅲ

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8

输出:3

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:
        def rootSum(root, targetSum):
            if not root:
                return 0

            ret = 0
            if root.val == targetSum:
                ret += 1
            ret += rootSum(root.left, targetSum - root.val)
            ret += rootSum(root.right, targetSum - root.val)
            return ret

        if not root:
            return 0
        res = rootSum(root, targetSum)
        res += self.pathSum(root.left, targetSum)
        res += self.pathSum(root.right, targetSum)
        return res

563.二叉树的坡度

给你一个二叉树的根节点 root ,计算并返回 整个树 的坡度 。

一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。

整个树 的坡度就是其所有节点的坡度之和。

输入:root = [1,2,3]

输出:1

class Solution:
    def findTilt(self, root: Optional[TreeNode]) -> int:
        def findSum(root):
            if not root:
                return 0

            rootsum = root.val + findSum(root.left) + findSum(root.right)
            return rootsum

        if not root:
            return 0

        res = abs(findSum(root.left) - findSum(root.right))
        return res + self.findTilt(root.left) + self.findTilt(root.right)

617.合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]

输出:[3,4,5,5,4,null,7]

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root2:
            return root1
        if not root1:
            return root2

        root1.val += root2.val
        root1.left = self.mergeTrees(root1.left, root2.left)
        root1.right = self.mergeTrees(root1.right, root2.right)
        return root1

508.出现次数最多的子树元素和

给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。

输入: root = [5,2,-3]

输出: [2,-3,4]

class Solution:
    def findFrequentTreeSum(self, root: Optional[TreeNode]) -> List[int]:
        def nodeSum(root):
            if not root:
                return 0

            nodesum = root.val + nodeSum(root.left) + nodeSum(root.right)
            table[nodesum] += 1
            return nodesum

        table = Counter()
        nodeSum(root)

        Max = max(table.values())
        res = []
        for key,value in table.items():
            if value == Max:
                res.append(key)
        return res

572.另一棵树的子树

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

输入:root = [3,4,5,1,2], subRoot = [4,1,2]

输出:true

class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:    
        def isSame(root, subRoot):
            if not root and not subRoot:
                return True
            elif not root or not subRoot:
                return False
            elif root.val != subRoot.val:
                return False
            else:
                return isSame(root.left, subRoot.left) and isSame(root.right, subRoot.right)

        def dfs(root, subRoot):
            res = isSame(root, subRoot)
            if res:
                return True
            elif not root:
                return False
            else:
                return dfs(root.left, subRoot) or dfs(root.right, subRoot)

        return dfs(root, subRoot)

543.二叉树的直径

给你一棵二叉树的根节点,返回该树的直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。

输入:root = [1,2,3,4,5]

输出:3

class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        self.res = 0

        def depth(root):
            if not root:
                return 0
            elif not root.left and not root.right:
                return 0
            else: 
                leftdepth = depth(root.left)
                rightdepth = depth(root.right)

                if not root.left or not root.right:
                    self.res = max(self.res, leftdepth + rightdepth + 1)
                else:
                    self.res = max(self.res, leftdepth + rightdepth + 2)

                return max(leftdepth, rightdepth) + 1

        depth(root)
        return self.res

654.最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

1.创建一个根节点,其值为 nums 中的最大值。

2.递归地在最大值 左边 的 子数组前缀上 构建左子树。

3.递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        def createTree(leftsub, rightsub):
            if leftsub == rightsub:
                return None 

            MaxNum, MaxSub = -1, -1
            for i in range(leftsub, rightsub):
                if nums[i] > MaxNum:
                    MaxNum = nums[i]
                    MaxSub = i
            node = TreeNode(MaxNum)
            node.left = createTree(leftsub, MaxSub)
            node.right = createTree(MaxSub+1, rightsub)
            return node

        length = len(nums)
        return createTree(0, length)

687.最长同值路径

给定一个二叉树的 root ,返回 最长的路径的长度 ,这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。两个节点之间的路径长度 由它们之间的边数表示。

输入:root = [5,4,5,1,1,5]

输出:2

class Solution:
    def longestUnivaluePath(self, root: Optional[TreeNode]) -> int:
        self.res = 0
        
        def SameCount(root):                // 统计路径个数
            leftnum, rightnum = 0, 0
            if root.left:                        // 若左结点存在,递归统计左节点路径个数
                temp = SameCount(root.left)
                if root.val == root.left.val:    // 若与左节点值相同,则将左结点路径个数加入
                    leftnum += (temp + 1)
            if root.right:                       // 若右结点存在,递归统计右结点路径个数
                temp = SameCount(root.right)
                if root.val == root.right.val:   // 若与右节点值相同,则将右节点路径个数加入
                    rightnum += (temp + 1)

            self.res = max(self.res, leftnum + rightnum)      // 根据当前结点的同值路径数更新全局最长同值路径
            return max(leftnum, rightnum)        // 向上一层递归调用返回当前最大的深度
            
        if not root:         // 根节点为空,直接退出
            return 0       
        SameCount(root)
        return self.res

102.二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

输入:root = [3,9,20,null,null,15,7]

输出:[[3],[9,20],[15,7]]

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []

        res = []
        q = deque([root])
        while q:
            vals = []
            for _ in range(len(q)):
                node = q.popleft()
                vals.append(node.val)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)              
            res.append(vals)
        return res

429.N叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

输入:root = [1,null,3,2,4,null,5,6]

输出:[[1],[3,2,4],[5,6]]

class Solution:
    def levelOrder(self, root: 'Node') -> List[List[int]]:
        if not root:
            return []

        ans = []
        q = deque([root])
        while q:
            vals = []
            for _ in range(len(q)):
                node = q.popleft()
                vals.append(node.val)
                for child in node.children:
                    q.append(child)
            ans.append(vals)
        return ans

690.员工的重要性

给定一个保存员工信息的数据结构,它包含了员工 唯一的 id ,重要度 和 直系下属的 id 。

比如,员工 1 是员工 2 的领导,员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] ,员工 2的 数据结构是 [2, 10, [3]] ,员工 3 的数据结构是 [3, 5, []] 。

现在输入一个公司的所有员工信息,以及单个员工 id ,返回这个员工和他所有下属的重要度之和。

输入:[[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1

输出:11

class Solution:
    def getImportance(self, employees: List['Employee'], id: int) -> int:
        if not employees:
            return 0

        def findem(employees, id):
            for employee in employees:
                if employee.id == id:
                    root = employee
                    return root

        res = 0
        q = deque([findem(employees, id)])
        while q:
            for _ in range(len(q)):
                em = q.popleft()
                res += em.importance
                for sub in em.subordinates:
                    q.append(findem(employees, sub))
        return res

559.N叉树的最大深度

给定一个 N 叉树,找到其最大深度。

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

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

输入:root = [1,null,3,2,4,null,5,6]

输出:3

class Solution:
    def maxDepth(self, root: 'Node') -> int:
        if not root:
            return 0

        res = 1
        q = deque([root])
        while q:
            depth = 0
            for _ in range(len(q)):
                node = q.popleft()
                for child in node.children:
                    depth = 1
                    q.append(child)
            res += depth
        return res

671.二叉树中第二小的节点

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。

更正式地说,即 root.val = min(root.left.val, root.right.val) 总成立。给出这样的一个二叉树,你需要输出所有节点中的 第二小的值 。如果第二小的值不存在的话,输出 -1 。

输入:root = [2,2,5,null,null,5,7]

输出:5

class Solution:
    def findSecondMinimumValue(self, root: Optional[TreeNode]) -> int:
        nums = [root.val]
        q = deque([root])
        while q:
            for _ in range(len(q)):
                node = q.popleft()
                if node.left:
                    if node.left.val < node.right.val:
                        nums.append(node.right.val)
                    if node.left.val > node.right.val:
                        nums.append(node.left.val)
                    q.append(node.left)
                    q.append(node.right)
        if len(nums) == 1:
            return -1
        else:
            Min = min(nums)
            nums.remove(Min)
            return min(nums)

513.找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

输入: root = [2,1,3]

输出: 1

class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        queue = Deque([root])
        res = 0
        while queue:
            res = queue[0].val
            for _ in range(len(queue)):
                node = queue.popleft() 
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)                             
        return res

515.在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

输入: root = [1,3,2,5,3,null,9]

输出: [1,3,9]

class Solution:
    def largestValues(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        queue = Deque([root])
        res = []
        while queue:
            num = queue[0].val
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.val > num:
                    num = node.val
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(num)
        return res

637.二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

输入:root = [3,9,20,null,null,15,7]

输出:[3.00000,14.50000,11.00000]

class Solution:
    def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        queue = Deque([root])
        res = []
        while queue:
            Sum, num = 0, 0
            for _ in range(len(queue)):
                node = queue.popleft()
                num += 1
                Sum += node.val
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(Sum/num)
        return res

103.二叉树的锯齿形层序遍历

给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

输入:root = [3,9,20,null,null,15,7]

输出:[[3],[20,9],[15,7]]

class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []

        res = []
        queue = Deque([root])
        flag = False
        while queue:
            num = []
            flag = not flag
            for _ in range(len(queue)):
                node = queue.popleft()
                num.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            if flag:
                res.append(num)
            else:
                res.append(num[::-1])
        return res

107.二叉树的层序遍历Ⅱ

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

输入:root = [3,9,20,null,null,15,7]

输出:[[15,7],[9,20],[3]]

257.二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

输入:root = [1,2,3,null,5]

输出:["1->2->5","1->3"]

class Solution:
    def binaryTreePaths(self, root):
        def findWay(root, path):
            if not root:
                return 

            path += str(root.val)
            if not root.left and not root.right:
                paths.append(path)
            else:
                path += '->'
                findWay(root.left, path)
                findWay(root.right, path)

        paths = []
        findWay(root, '')
        return paths

623.在二叉树中增加一行

给定一个二叉树的根 root 和两个整数 val 和 depth ,在给定的深度 depth 处添加一个值为 val 的节点行。注意,根节点 root 位于深度 1 。

输入: root = [4,2,6,3,1,5], val = 1, depth = 2

输出: [4,1,1,2,null,null,6,3,1,5]

class Solution:
    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:
        if depth == 1:
            new_node = TreeNode(val)
            new_node.left = root
            return new_node

        queue = Deque([root])
        for i in range(2, depth):
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        for q in queue:
            child_left = TreeNode(val)
            child_left.left = q.left
            q.left = child_left

            child_right = TreeNode(val)
            child_right.right = q.right
            q.right = child_right
        return root

653.两数之和Ⅳ

给定一个二叉搜索树 root 和一个目标结果 k,如果二叉搜索树中存在两个元素且它们的和等于给定的目标结果,则返回 true.

输入: root = [5,3,6,2,4,null,7], k = 9

输出: true

class Solution:
    def findTarget(self, root: Optional[TreeNode], k: int) -> bool:
        def bfs(root, k):
            queue = Deque([root])
            while queue:
                for _ in range(len(queue)):
                    node = queue.popleft()
                    if k-node.val in nums:
                        return True
                    else:
                        nums.add(node.val)
                        if node.left:
                            queue.append(node.left)
                        if node.right:
                            queue.append(node.right)
            return False

        nums = set()
        return bfs(root, k)

104.二叉树的最大深度

给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。

输入:[3,9,20,null,null,15,7]

输出:3

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        res = 0
        queue = Deque([root])
        while queue:
            res += 1
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return res

111.二叉树的最小深度

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

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

输入:root = [3,9,20,null,null,15,7]

输出:2

class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        res = 0
        queue = Deque([root])
        while queue:
            res += 1
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
                if not node.left and not node.right:
                    return res

112.路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和  targetSum 。如果存在,返回 true ;否则,返回 false 。

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22

输出:true

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        def dfs(root, targetSum):
            if not root:
                return False

            if not root.left and not root.right:
                if root.val == targetSum:
                    return True
                else:
                    return False
            else:
                return dfs(root.left, targetSum-root.val) or dfs(root.right, targetSum-root.val)

        return dfs(root, targetSum)

113.路径总和Ⅱ

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22

输出:[[5,4,11,2],[5,8,4,5]]

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        def dfs(root, targetSum):
            if not root:
                return 

            if not root.left and not root.right: 
                if root.val == targetSum:
                    path.append(root.val)
                    res.append(path[:])
                    path.pop()
                else:
                    return
            else:
                path.append(root.val)
                dfs(root.left, targetSum-root.val)
                dfs(root.right, targetSum-root.val)
                path.pop()

        res = []
        path = []
        dfs(root, targetSum)
        return res

129.求根节点到叶节点数字之和

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。每条从根节点到叶节点的路径都代表一个数字:例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。计算从根节点到叶节点生成的 所有数字之和 。

输入:root = [1,2,3]

输出:25

class Solution:
    def sumNumbers(self, root: Optional[TreeNode]) -> int:
        def dfs(root, temp):
            if not root:
                return

            temp = temp*10 + root.val
            if not root.left and not root.right:
                res.append(temp)
            dfs(root.left, temp)
            dfs(root.right, temp)

        temp = 0
        res = []
        dfs(root, temp)
        return sum(res)

404.左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

输入: root = [3,9,20,null,null,15,7]

输出: 24

def dfs(root, flag_left):
    if not root:
        return

    if not root.left and not root.right and flag_left:
        res.append(root.val)
    else:
        dfs(root.left, True)
        dfs(root.right, False)

res = []
dfs(root, False)
return sum(res)

199.二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

输入: [1,2,3,null,5,null,4]

输出: [1,3,4]

class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        res = []
        queue = Deque([root])
        while queue:
            num = 0
            for _ in range(len(queue)):
                node = queue.popleft()
                num = node.val
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(num)
        return res

116.填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

输入:root = [1,2,3,4,5,6,7]

输出:[1,#,2,3,#,4,5,6,7,#]

class Solution:
    def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        if not root:
            return []

        queue = Deque([root])
        while queue:
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if i < size - 1:
                    node.next = queue[0]
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

117.充每个节点的下一个右侧节点指针Ⅱ

给定一个二叉树,填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

输入:root = [1,2,3,4,5,null,7]

输出:[1,#,2,3,#,4,5,7,#]

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return None

        queue = collections.deque([root])
        while queue:
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if i < size-1:
                    node.next = queue[0]
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

144.二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

输入:root = [1,null,2,3]

输出:[1,2,3]

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        def dfs(root):
            if not root:
                return

            res.append(root.val)
            dfs(root.left)
            dfs(root.right)

        res = []
        dfs(root)
        return res

589.N叉树的前序遍历

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

输入:root = [1,null,3,2,4,null,5,6]

输出:[1,3,5,6,2,4]

class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        def dfs(root):
            if not root:
                return

            res.append(root.val)
            for ch in root.children:
                dfs(ch)

        res = []
        dfs(root)
        return res

606.根据二叉树创建字符串

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

输入:root = [1,2,3,4]

输出:"1(2(4))(3)"

class Solution:
    def tree2str(self, root: Optional[TreeNode]) -> str:
        def dfs(root):
            if not root:
                return ""

            if not root.left and not root.right:
                return str(root.val)
            elif not root.right:
                return f"{root.val}({dfs(root.left)})"
            elif not root.left:
                return f"{root.val}()({dfs(root.right)})"
            else:
                return f"{root.val}({dfs(root.left)})({dfs(root.right)})"

        return dfs(root)

652.寻找重复的子树

给你一棵二叉树的根节点 root ,返回所有 重复的子树 。对于同一类的重复子树,你只需要返回其中任意 一棵 的根结点即可。如果两棵树具有 相同的结构 和 相同的结点值 ,则认为二者是 重复 的。

输入:root = [1,2,3,4,null,2,4,null,null,4]

输出:[[2,4],[4]]

class Solution:
    def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
        def dfs(root):
            if not root:
                return 

            path = f"{root.val}({dfs(root.left)})({dfs(root.right)})"
            if path in paths:
                if path not in repeat:
                    res.append(root)
                    repeat.add(path)
            else:
                paths.add(path)
            return path

        paths, repeat = set(), set()
        res = []
        dfs(root.left)
        dfs(root.right)
        return res

449.序列化和反序列化二叉搜索树

序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。

设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。

输入:root = [2,1,3]

输出:[2,1,3]

class Codec:

    def serialize(self, root: Optional[TreeNode]) -> str:
        """Encodes a tree to a single string.
        """
        def dfs(root):
            if not root:
                res.append('')
                return

            res.append(str(root.val))
            dfs(root.left)
            dfs(root.right)

        res = []
        dfs(root)
        return ','.join(res)

    def deserialize(self, data: str) -> Optional[TreeNode]:
        """Decodes your encoded data to tree.
        """
        def CreateTree(s):
            if not s:
                return None

            node = TreeNode(int(s))
            node.left = CreateTree(nums.pop(0))
            node.right = CreateTree(nums.pop(0))
            return node

        nums = data.split(',')
        root = CreateTree(nums.pop(0))
        return root

145.二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历

输入:root = [1,null,2,3]

输出:[3,2,1]

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        def postorder(root):
            if not root:
                return 

            postorder(root.left)
            postorder(root.right)
            res.append(root.val)

        res = []
        postorder(root)
        return res

590.N叉树的后序遍历

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

输入:root = [1,null,3,2,4,null,5,6]

输出:[5,6,3,2,4,1]

class Solution:
    def postorder(self, root: 'Node') -> List[int]:
        def postdfs(root):
            if not root:
                return

            for ch in root.children:
                postdfs(ch)
            res.append(root.val)
        res = []
        postdfs(root)
        return res

94.二叉树的中序遍历

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

输入:root = [1,null,2,3]

输出:[1,3,2]

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        def inorder(root):
            if not root:
                return 

            inorder(root.left)
            res.append(root.val)
            inorder(root.right)
        res = []
        inorder(root)
        return res

700.二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

输入:root = [4,2,7,1,3], val = 2

输出:[2,1,3]

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        def dfs(root, val):
            if not root:
                return None

            if root.val == val:
                return root
            elif root.val < val:
                return dfs(root.right, val)
            else:
                return dfs(root.left, val)
        return dfs(root, val)

530.二叉搜索树的最小绝对差

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值。

输入:root = [4,2,6,1,3]

输出:1

class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        def inorder(root, res, flag):
            if not root:
                return

            inorder(root.left, self.res, self.flag)
            if self.flag == -1:
                self.flag = root.val
            else:
                self.res = min(root.val - self.flag, self.res)
                self.flag = root.val
            inorder(root.right, self.res, self.flag)

        self.res = 2**17
        self.flag = -1
        inorder(root, self.res, self.flag)
        return self.res

538.把二叉搜索树转换为累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]

输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

class Solution:
    def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        def inorder(root):
            if not root:
                return

            inorder(root.right)
            nonlocal s
            s += root.val
            root.val = s 
            inorder(root.left)

        s = 0       
        inorder(root)
        return root

230.二叉搜索树中第K小的元素

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

输入:root = [3,1,4,null,2], k = 1

输出:1

class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        st = []
        p = root
        while p or st:
            while p:
                st.append(p)
                p = p.left
            p = st.pop()
            if k == 1:
                return p.val
            else:
                k -= 1
            p = p.right

98.验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

输入:root = [2,1,3]

输出:true

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        st = []
        p = root
        pre = -inf
        while p or st:
            while p:
                st.append(p)
                p = p.left
            p = st.pop()
            if p.val <= pre:
                return False
            pre = p.val
            p = p.right
        return True

173.二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:

BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于BST 中的数字,且该数字小于 BST 中的任何元素。

boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。

int next()将指针向右移动,然后返回指针处的数字。

输入:

["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]

[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]

输出:

[null, 3, 7, true, 9, true, 15, true, 20, false]

class BSTIterator:

    def __init__(self, root: Optional[TreeNode]):
        self.queue = collections.deque()
        q = root
        st = []
        while q or st:
            while q:
                st.append(q)
                q = q.left
            q = st.pop()
            self.queue.append(q.val)
            q = q.right

    def next(self) -> int:
        return self.queue.popleft()

    def hasNext(self) -> bool:
        return len(self.queue) > 0

669.修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

输入:root = [1,0,2], low = 1, high = 2

输出:[1,null,2]

class Solution:
    def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        def inorder(root):
            while not root:
                return

            root.left = inorder(root.left)
            if root.val < low:
                root.right = inorder(root.right)
                return root.right
            if root.val > high:
                return root.left
            root.right = inorder(root.right)
            return root

        new_root = inorder(root)
        return new_root

450.删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

输入:root = [5,3,6,2,4,null,7], key = 3

输出:[5,4,6,2,null,null,7]

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        def dfs(root, node_right):
            if not root:
                return node_right

            if root.val < key:
                root.right = dfs(root.right, node_right)
                return root
            elif root.val > key:
                root.left = dfs(root.left, node_right)
                return root
            else:
                return dfs(root.left, root.right)

        return dfs(root, None)

110.平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

输入:root = [1,2,2,3,3,null,null,4,4]

输出:false

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def dfs(root) -> int:
            if not root:
                return 0

            dep1 = dfs(root.left)
            dep2 = dfs(root.right)
            if abs(dep1 - dep2) > 1:
                nonlocal flag
                flag = False
            return max(dep1, dep2) + 1

        flag = True
        dfs(root)
        return flag

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

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

输入:nums = [-10,-3,0,5,9]

输出:[0,-3,9,-10,null,5]

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        def createTree(low, up):
            if low > up:
                return 
            mid = (low + up) // 2
            node = TreeNode(nums[mid])
            node.left = createTree(low, mid - 1)
            node.right = createTree(mid + 1, up)
            return node

        return createTree(0, len(nums) - 1)

114.二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。

展开后的单链表应该与二叉树 先序遍历 顺序相同。

输入:root = [1,2,5,3,4,null,6]

输出:[1,null,2,null,3,null,4,null,5,null,6]

class Solution:
    def flatten(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        def preorder(root):
            if not root:
                return
            preorderNum.append(root)
            preorder(root.left)
            preorder(root.right)

        preorderNum = []
        preorder(root)
        size = len(preorderNum)
        for i in range(size - 1):
            cur, last = preorderNum[i], preorderNum[i+1]
            cur.left = None
            cur.right = last

109.有序链表转换二叉搜索树

给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。

输入: head = [-10,-3,0,5,9]

输出: [0,-3,9,-10,null,5]

class Solution:
    def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
        def getMid(low, up):
            slow, fast = low, low
            while fast != up and fast.next != up:
                fast = fast.next.next
                slow = slow.next
            return slow

        def dfs(low, up):
            if low == up:
                return
            midnum = getMid(low, up)
            node = TreeNode(midnum.val)
            node.left = dfs(low, midnum)
            node.right = dfs(midnum.next, up)
            return node

        return dfs(head, None)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值