leetcode二叉树相关题型python实现

from collections import deque
from typing import List, Optional


# 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 SolutionPreorderTraversal:
    """二叉树的递归遍历"""

    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 保存结果
        result = []

        def traversal(root: TreeNode):
            if root == None:
                return
            result.append(root.val)  # 前序
            traversal(root.left)  # 左
            traversal(root.right)  # 右

        traversal(root)
        return result


# 中序遍历-递归-LC94_二叉树的中序遍历
class SolutionInorderTraversal:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result = []

        def traversal(root: TreeNode):
            if root == None:
                return
            traversal(root.left)  # 左
            result.append(root.val)  # 中序
            traversal(root.right)  # 右

        traversal(root)
        return result


# 后序遍历-递归-LC145_二叉树的后序遍历
class SolutionPostorderTraversal:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        result = []

        def traversal(root: TreeNode):
            if root == None:
                return
            traversal(root.left)  # 左
            traversal(root.right)  # 右
            result.append(root.val)  # 后序

        traversal(root)
        return result


class SolutionLevelOrder:
    """二叉树层序遍历"""

    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        res = []

        if not root:
            return res
        from collections import deque
        queue = deque([root])
        while queue:
            size = len(queue)
            sig_res = []
            for _ in range(size):
                tmp = queue.popleft()
                sig_res.append(tmp.val)
                if tmp.left:
                    queue.append(tmp.left)
                if tmp.right:
                    queue.append(tmp.right)
            res.append(sig_res)

        return res


class SolutionInvertTree:
    """翻转二叉树"""

    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


class SolutionIsSymmetric:
    """对称二叉树"""

    def isSymmetric(self, root: 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 False
        elif left != None and right == None:
            return False
        elif left == None and right == None:
            return True
        # 排除了空节点,再排除数值不相同的情况
        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


class solutionMaxdepth:
    """二叉树的最大深度"""

    def maxdepth(self, root) -> int:
        return self.getdepth(root)

    def getdepth(self, node):
        if not node:
            return 0
        leftheight = self.getdepth(node.left)  # 左
        rightheight = self.getdepth(node.right)  # 右
        height = 1 + max(leftheight, rightheight)  # 中
        return height


class SolutionMinDepth:
    """二叉树的最小深度"""

    def minDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        if not root.left and not root.right:
            return 1

        min_depth = 10 ** 9
        if root.left:
            min_depth = min(self.minDepth(root.left), min_depth)  # 获得左子树的最小高度
        if root.right:
            min_depth = min(self.minDepth(root.right), min_depth)  # 获得右子树的最小高度
        return min_depth + 1


class SolutionCountNodes:
    """完全二叉树的节点个数"""

    def countNodes(self, root: TreeNode) -> int:
        return self.getNodesNum(root)

    def getNodesNum(self, cur):
        if not cur:
            return 0
        leftNum = self.getNodesNum(cur.left)  # 左
        rightNum = self.getNodesNum(cur.right)  # 右
        treeNum = leftNum + rightNum + 1  # 中
        return treeNum


class SolutionIsBalanced:
    """平衡二叉树"""

    def isBalanced(self, root: TreeNode) -> bool:
        if self.get_height(root) != -1:
            return True
        else:
            return False

    def get_height(self, root: TreeNode) -> int:
        # Base Case
        if not root:
            return 0
        # 左
        if (left_height := self.get_height(root.left)) == -1:
            return -1
        # 右
        if (right_height := self.get_height(root.right)) == -1:
            return -1
        # 中
        if abs(left_height - right_height) > 1:
            return -1
        else:
            return 1 + max(left_height, right_height)


class SolutionBinaryTreePaths:
    """二叉树的所有路径"""

    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        res = []
        path = []

        def trans(current_node):
            path.append(current_node.val)
            if current_node.left is None and current_node.right is None:
                res.append("->".join([str(i) for i in path[:]]))
            if current_node.left:
                trans(current_node.left)
                path.pop()
            if current_node.right:
                trans(current_node.right)
                path.pop()

        trans(root)
        return res


class SolutionSumOfLeftLeaves:
    """左叶子之和"""

    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        left_sum = self.sumOfLeftLeaves(root.left)
        if root.left and root.left.left is None and root.left.right is None:
            left_sum = root.left.val
        right_sum = self.sumOfLeftLeaves(root.right)
        return left_sum + right_sum


class SolutionFindBottomLeftValue:
    """找树左下角的值"""

    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        queue = deque([root])
        if root is None:
            return []
        while queue:
            temp = []
            size = len(queue)
            for i in range(size):
                current_node = queue.popleft()
                temp.append(current_node.val)
                if current_node.left:
                    queue.append(current_node.left)
                if current_node.right:
                    queue.append(current_node.right)
            res = temp[0]
        return res


class SolutionHasPathSum:
    """路径总和"""

    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        res = []
        path = []
        if not root:
            return False

        def trans(root, targetSum):
            path.append(root.val)
            if root.left is None and root.right is None:
                if sum(path) == targetSum:
                    res.append(path[:])
            if root.left:
                trans(root.left, targetSum)
                path.pop()
            if root.right:
                trans(root.right, targetSum)
                path.pop()

        trans(root, targetSum)
        return True if res else False


class SolutionBuildTree:
    """从中序与后序遍历序列构造二叉树"""

    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        # 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
        if not preorder:
            return None

        # 第二步: 前序遍历的第一个就是当前的中间节点.
        root_val = preorder[0]
        root = TreeNode(root_val)

        # 第三步: 找切割点.
        separator_idx = inorder.index(root_val)

        # 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
        inorder_left = inorder[:separator_idx]
        inorder_right = inorder[separator_idx + 1:]

        # 第五步: 切割preorder数组. 得到preorder数组的左,右半边.
        # ⭐️ 重点1: 中序数组大小一定跟前序数组大小是相同的.
        preorder_left = preorder[1:1 + len(inorder_left)]
        preorder_right = preorder[1 + len(inorder_left):]

        # 第六步: 递归
        root.left = self.buildTree(preorder_left, inorder_left)
        root.right = self.buildTree(preorder_right, inorder_right)

        return root


class SolutionConstructMaximumBinaryTree:
    """最大二叉树"""

    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if not nums:
            return None
        max_val = max(nums)
        index_max = nums.index(max_val)
        root = TreeNode(max_val)
        left_tree_list = nums[:index_max]
        right_tree_list = nums[index_max + 1:]
        root.left = self.constructMaximumBinaryTree(left_tree_list)
        root.right = self.constructMaximumBinaryTree(right_tree_list)
        return root


class SolutionMergeTrees:
    """合并二叉树"""

    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        # 递归终止条件:
        #  但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
        if not root1:
            return root2
        if not root2:
            return root1
        # 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
        root1.val += root2.val  # 中
        root1.left = self.mergeTrees(root1.left, root2.left)  # 左
        root1.right = self.mergeTrees(root1.right, root2.right)  # 右

        return root1  # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.


class SolutionSearchBST:
    """二叉搜索树中的搜索"""

    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        def trans(current_node, val):
            if current_node is None:
                return None
            if current_node.val == val:
                return current_node
            node1 = trans(current_node.left, val)
            node2 = trans(current_node.right, val)
            if node1:
                return node1
            elif node2:
                return node2
            else:
                return None

        res = trans(root, val)
        return res


class SolutionIsValidBST:
    """是否是有效二叉搜索树"""

    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        res = []

        def trans(root, res):
            if not root:
                return
            trans(root.left, res)
            res.append(root.val)
            trans(root.right, res)

        trans(root, res)
        return res == sorted(res) and len(res) == len(set(res))


class SolutionGetMinimumDifference:
    """二叉搜索树的最小绝对差"""

    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        def trans(root, res):
            if not root:
                return
            res.append(root.val)
            trans(root.left, res)
            trans(root.right, res)

        res = []
        trans(root, res)
        res.sort()
        min_val = res[1] - res[0]
        for i in range(1, len(res)):
            temp = abs(res[i] - res[i - 1])
            min_val = min(min_val, temp)
        return min_val


class SolutionFindMode:
    """二叉搜索树中的众数"""

    def findMode(self, root: Optional[TreeNode]):
        res = []

        def trans(root, res):
            if not root:
                return
            res.append(root.val)
            trans(root.left, res)
            trans(root.right, res)

        trans(root, res)
        from collections import Counter
        cnt = Counter(res)
        max_num = cnt.most_common(1)[0][1]
        result = []
        for key, item in cnt.items():
            if item == max_num:
                result.append(key)
        return result


class SolutionLowestCommonAncestor:
    """ 二叉树的最近公共祖先"""

    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        def trans(root, p, q):
            if root is None:
                return None
            if root == p or root == q:
                return root
            node_left = trans(root.left, p, q)
            node_right = trans(root.right, p, q)
            if node_left and node_right:
                return root
            if node_left and not node_right:
                return node_left
            if not node_left and node_right:
                return node_right
            else:
                return None

        node = trans(root, p, q)
        return node


class SolutionLowestCommonAncestor:
    """二叉搜索树的最近公共祖先"""

    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        def trans(root, p, q):
            if root is None:
                return None
            if root.val > q.val and root.val > p.val:
                return trans(root.left, p, q)
            if root.val < q.val and root.val < p.val:
                return trans(root.right, p, q)
            return root

        node = trans(root, p, q)
        return node


class SolutionInsertIntoBST:
    """二叉搜索树中的插入操作"""

    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if root is None:
            return TreeNode(val)
        if root.val > val:
            root.left = self.insertIntoBST(root.left, val)
        if root.val < val:
            root.right = self.insertIntoBST(root.right, val)
        return root


class SolutionDeleteNode:
    """删除二叉树"""

    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        def trans(current_node, key):
            if not current_node:
                return None
            if current_node.val == key:
                if current_node.left is None and current_node.right is None:
                    return None
                elif current_node.left and not current_node.right:
                    return current_node.left
                elif current_node.right and not current_node.left:
                    return current_node.right
                else:
                    cur = current_node.right
                    while cur.left:
                        cur = cur.left
                    cur.left = current_node.left
                    return current_node.right
            if current_node.val > key:
                current_node.left = trans(current_node.left, key)
            if current_node.val < key:
                current_node.right = trans(current_node.right, key)
            return current_node

        res = trans(root, key)
        return res


class SolutionTrimBST:
    """修剪二叉树"""

    def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        def trans(current_node, low, high):
            if not current_node:
                return None
            if current_node.val < low:
                return trans(current_node.right, low, high)
            if current_node.val > high:
                return trans(current_node.left, low, high)
            current_node.left = trans(current_node.left, low, high)
            current_node.right = trans(current_node.right, low, high)
            return current_node

        res = trans(root, low, high)
        return res


class SolutionSortedArrayToBST:
    """将有序数组转换为二叉搜索树"""

    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        def trans(nums, left, right):
            if left > right:
                return None
            mid = (left + right) // 2
            root = TreeNode(nums[mid])
            root.left = trans(nums, left, mid - 1)
            root.right = trans(nums, mid + 1, right)
            return root

        res = trans(nums, 0, len(nums) - 1)
        return res


class SolutionConvertBST:
    """把二叉搜索树转换为累加树"""

    def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        pre = 0

        def trans(root):
            nonlocal pre
            if not root:
                return
            trans(root.right)
            root.val += pre
            pre = root.val
            trans(root.left)

        trans(root)
        return root

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值