【leetcode37-51】二叉树

94. 二叉树的中序遍历

在这里插入图片描述

# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)
        return left + [root.val] + right

104.二叉树的最大深度

在这里插入图片描述

# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        return 1+max(self.maxDepth(root.left), self.maxDepth(root.right))

226.翻转二叉树

在这里插入图片描述

# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root: 
            return 
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

101.对称二叉树

在这里插入图片描述

【递归法】
class Solution:
    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

102.二叉树的层序遍历

在这里插入图片描述

双端队列: collections.deque()
从开端弹出元素 popleft() ;从尾端弹出元素 , pop()

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        res = []
        if root == None: return []
        deque = collections.deque([root])
        while deque: 
            level = []
            for _ in range(len(deque)):
                node = deque.popleft()
                level.append(node.val)
                if node.left:
                    deque.append(node.left)
                if node.right:
                    deque.append(node.right)
            res.append(level)
        return res
                    
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        res = []
        self.helper(root, 0, res)
        return res
    
    def helper(self, node, level, res):
        if not node:
            return
        if len(res) == level:  #先按层数,把【】里面套的【】全都建好
            res.append([])

        res[level].append(node.val)
        self.helper(node.left, level + 1, res)  #指定框子
        self.helper(node.right, level + 1, res)

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

在这里插入图片描述

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

98.验证二叉搜索树【!】

在这里插入图片描述
中序遍历
利用pre和cur双指针

class Solution:
    def __init__(self):
        self.pre = None  # 用来记录前一个节点

    def isValidBST(self, root):
        if root is None:
            return True

        left = self.isValidBST(root.left)

        if self.pre is not None and self.pre.val >= root.val:
            return False
        self.pre = root  # 记录前一个节点

        right = self.isValidBST(root.right)
        return left and right

递归法(版本一)利用中序递增性质,转换成数组

class Solution:
    def __init__(self):
        self.vec = []

    def traversal(self, root):
        if root is None:
            return
        self.traversal(root.left)
        self.vec.append(root.val)  # 将二叉搜索树转换为有序数组
        self.traversal(root.right)

    def isValidBST(self, root):
        self.vec = []  # 清空数组
        self.traversal(root)
        for i in range(1, len(self.vec)):
            # 注意要小于等于,搜索树里不能有相同元素
            if self.vec[i] <= self.vec[i - 1]:
                return False
        return True

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

在这里插入图片描述
递归法(版本一)利用中序递增性质,转换成一个递增数组

class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        self.vec = []
        self.travel(root)
        return self.vec[k-1] 
        
    def travel(self, root): 
        if not root: 
        	return None
        self.travel(root.left)
        self.vec.append(root.val)
        self.travel(root.right)
    

199.二叉树的右视图

在这里插入图片描述
== 层序遍历==

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

        queue = collections.deque([root])
        while queue:
            level_length = len(queue)  #给一个迭代前的长度,不要放在迭代里面,要不然会更新改变
            for _ in range(len(queue)):  #这个len(queue) 不会更新
                node = queue.popleft()
                if _ == level_length-1:
                    res.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return res

114.二叉树展开为链表【后序遍历】

在这里插入图片描述
后序遍历

class Solution:
    def flatten(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if not root: 
            return 
        
        self.flatten(root.left)  ##左子树变成一长条
        self.flatten(root.right)   ##右子树变成一长条

 #### root.right=左子树,右子树接到左节点的末尾 ####
        left = root.left
        right = root.right

       
        root.left = None
        root.right = left
        cur = root  #cur一定是赋值给root,而不是root.left,如果root.left为空,会报错
     
        while cur.right:
            cur = cur.right
        cur.right = right

105.从前序与中序遍历序列构造二叉树【前序】

在这里插入图片描述
前序遍历

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:  #中左右, 左中右
        if  len(preorder) == 0 : 
            return None
        root_val = preorder[0]
        root = TreeNode(val = root_val)  #建立头节点
        split_index = inorder.index(root_val)  #找到分割点
        root.left = self.buildTree(preorder[1:split_index+1], inorder[:split_index])
        root.right = self.buildTree(preorder[split_index+1:], inorder[split_index+1:])
        return root

437.路径总和3【较难】

在这里插入图片描述
在这里插入图片描述

class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:
        if not root:
            return 0
        left_cnt = self.pathSum(root.left, targetSum)
        right_cnt = self.pathSum(root.right, targetSum)
         #路径总和 = root开始的路径数 + 左子树路径总和 + 右子树路径总和    
        return self.rootsum(root, targetSum)+ left_cnt+ right_cnt 

    def rootsum(self, root,targetSum)-> int:  #计算root到某个节点的和等于targetsum的路径数目
        if not root: 
            return 0

        ans = 0
        if root.val == targetSum:   #找到路径
            ans += 1
        left = self.rootsum(root.right, targetSum-root.val)
        right = self.rootsum(root.left, targetSum-root.val)
        return ans + left + right  #当前位置的结果+往左走+往右走

236.二叉树的最近公共祖先【后序遍历】

在这里插入图片描述

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root == p or root == q: return root
        if root == None: return root

        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right,p,q)
   #左右有一个空,则返回另一个不空的,如果都空,则返回None;都不空,返回root
        if left != None and right == None: 
            return left
        elif left == None and right != None:
            return right
        elif left != None and right != None:
            return root
        else :
            return None

543.二叉树的直径【全局变量】

在这里插入图片描述

二叉树的直径,因为他不一定经过root,但是,最长路径,一定是有个公共祖先,所以,只要有个全局变量self.max记录就行

# 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 diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        if not root:  
             return 0
        self.maxwid = 0
        self.findwid(root)
        return self.maxwid
    
    def findwid(self, root) -> int:   #给一个节点,计算过这个node的树的直径  left+right
        if not root: 
            return 0
        left = self.findwid(root.left)  #左子树的高度
        right = self.findwid(root.right)
        self.maxwid = max(self.maxwid, left + right )   #更新最大直径
        return max(left, right) + 1

124.二叉树中最大的路径和【全局变量】

在这里插入图片描述

class Solution:
    def maxPathSum(self, root: Optional[TreeNode]) -> int:
        self.maxlen = -float('inf')
        if not root: 
            return self.maxlen
        self.dfs(root)
        return self.maxlen
        
    def dfs(self, root):  #返回从根节点到节点的最大路径和【路径至少包含一个节点】
        if not root: 
            return 0
        left = max(self.dfs(root.left),0)
        right = max(self.dfs(root.right),0)
        self.maxlen = max(self.maxlen, left + right + root.val)
        return root.val + max(left, right)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值