Leetcode Day-8 (hot100 二叉树专题)

层序遍历模版

queue = [root]
while queue:
	length = len(queue)
	while (length > 0):
		node = queue.pop(0)
		if node.left ->if node.right -> 加
		length -= 1

101 对称二叉树

第一个想法是用递归, 看左边对称不, 右边对称不, 但是整个树对称没必要子树也对称啊
第二个想法是耍小聪明, 用中序遍历得到res, 看res和res[::-1相等吗,🤡了

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

看评论其实把null给一个值比如-100就行

543: 求二叉树的直径

这道题真的可以, 考察的挺全面

class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        self.ans = 1
        def dfs(root):
            if root == None:
                return 0
            L = dfs(root.left)
            R = dfs(root.right)
            self.ans = max(self.ans, 1 + L + R)
            return 1 + max(L, R)
        dfs(root)
        return self.ans - 1

最后-1是指数问题, 段数=树数 - 1

注意先把L和R给赋值了, 不然下面的你再用dfs会增加计算

108: 有序数组转换为二叉树

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

最优雅的地方是nums[mid+1:], 在切片操作中, mid+1超出范围的话直接返回空列表, 太优雅了

98: 判断是否为二叉树

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if root == None:
            return True
        if root.left == None and root.right != None:
            return False
        if root.left != None and root.right == None:
            return False
        if root.left == None and root.right == None:
            return True
        return self.isValidBST(root.left) and self.isValidBST(root.right) & root.left.val < root.right.val

又犯了同一个错误, 这种题是不能递归的, 即使左侧是valid, 能保证左侧的一定比右侧的小吗

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        def help(low, high, root):
            if root == None:
                return True
            return low < root.val < high and help(low, root.val, root.left) and help(root.val, high, root.right)
        return help(-float('inf'), float('inf'), root)

当然直接中序遍历看是不是递增也是很好的解法

199: 从右侧看二叉树

一般方法:层序遍历
灵神:

思路:先递归右子树,再递归左子树,当某个深度首次到达时,对应的节点就在右视图中。

class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        ans = []
        def dfs(node: Optional[TreeNode], depth: int) -> None:
            if node is None:
                return
            if depth == len(ans):  # 这个深度首次遇到
                ans.append(node.val)
            dfs(node.right, depth + 1)  # 先递归右子树,保证首次遇到的一定是最右边的节点
            dfs(node.left, depth + 1)
        dfs(root, 0)
        return ans

437 求二叉树里节点值之和等于c的路径数目

我们首先定义 rootSum(p,val) 表示以节点 p 为起点向下且满足路径总和为 val 的路径数目

class Solution:
    def pathSum(self, root: TreeNode, targetSum: int) -> int:
        def rootSum(root, targetSum):
            if root is None:
                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 root is None:
            return 0
            
        ret = rootSum(root, targetSum)
        ret += self.pathSum(root.left, targetSum)
        ret += self.pathSum(root.right, targetSum)
        return ret

110 一颗二叉树是否平衡

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def dfs(root):
            if root is None:
                return 0
            return 1 + max(dfs(root.left), dfs(root.right))
        if root == None:
            return True
        h_l = dfs(root.left)
        h_r = dfs(root.right)
        return abs(h_l - h_r) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)        

只能说写的太丑陋了

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def height(root: TreeNode) -> int:
            if not root:
                return 0
            leftHeight = height(root.left)
            rightHeight = height(root.right)
            if leftHeight == -1 or rightHeight == -1 or abs(leftHeight - rightHeight) > 1:
                return -1
            else:
                return max(leftHeight, rightHeight) + 1

        return height(root) >= 0

这种方法能够让error信号顺着递归传上去

236 最近公共祖先

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        
        def find(root, target):
            if root == target:
                return True
            if root == None:
                return False
            return find(root.left, target) or find(root.right, target)

        l = find(root.left, p)
        r = find(root.right, q)
        if root == p or root == q:
            return root
        if l and r:
            return root
        if l and not r:
            return self.lowestCommonAncestor(root.left, p, q)
        if not l and r:
            return self.lowestCommonAncestor(root.right, p, q)     

写的丑陋, 同时判断条件很多

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root or root == p or root == q:
            return root
        
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        
        if left is None:
            return right
        if right is None:
            return left
        return root
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值