2021-07-13:二叉树1

二叉树题目:

# 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: TreeNode) -> int:
        if not root:return 0
        return max(self.maxDepthhelper(root.left,1),self.maxDepthhelper(root.right,1))
    def maxDepthhelper(self,node,d):
        if node:
            return max(self.maxDepthhelper(node.left,d+1),self.maxDepthhelper(node.right,d+1))
        return d
            

更简便:

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

            

递归模板:

 

# 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 isBalanced(self, root: TreeNode) -> bool:
        self.result = True
        self.maxdepth(root)
        return self.result
    def maxdepth(self,root):
        if not root: return 0
        l = self.maxdepth(root.left)
        r = self.maxdepth(root.right)
        if abs(l-r)>1: 
            self.result = False
        return 1 +max(l,r)
# 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 isBalanced(self, root: TreeNode) -> bool:
        return self.maxdepth(root) != -1
        return self.result
    def maxdepth(self,root):
        if not root: return 0
        l = self.maxdepth(root.left)
        if l == -1: return -1
        r = self.maxdepth(root.right)
        if r == -1: return -1
        return max(l,r)+1 if abs(l-r)<=1 else -1

# 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: TreeNode) -> int:
    # 3个变量,左边深度,右边深度,本层的路径长度最大值
        if not root: return 0
        self.maxd = 0
        self.maxdepth(root)
        return self.maxd
    def maxdepth(self,root):
        if not root:
            return 0
        l = self.maxdepth(root.left)
        r = self.maxdepth(root.right)
        self.maxd = max(self.maxd,l+r)
        return max(l,r)+1 
    

 

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

问题代码:

# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        root3 = TreeNode(0)
        self.mergehelper(root1,root2,root3)
        return root3
    def mergehelper(self,root1,root2,root3):
        if not root1 and root2:
            return
        elif not root1:
            root3 = root2
        elif not root2:
            root3 = root1
        else:
            root3 = TreeNode(root1.val+root2.val)
            self.mergehelper(root1.left,root2.left,root3.left)
            self.mergehelper(root1.right,root2.right,root3.right)

问题:必须要存在这个节点,不能指向None之后给他赋值

循环用函数的套路:

return的东西刚好等于要改的地方

# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        if not root1 and not root2:
            return None
        elif not root1:
            return root2
        elif not root2:
            return root1
        else:
            root3 = TreeNode(root1.val+root2.val)
            root3.left = self.mergeTrees(root1.left,root2.left)
            root3.right = self.mergeTrees(root1.right,root2.right)
            return root3

# 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 hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
        if not root:
            return False
        self.result = False
        self.sumhelper(root,targetSum,root.val)
        return self.result
    def sumhelper(self,root,targetSum,sum1):
        if not root.left and not root.right:
            if sum1 == targetSum:
                self.result = True 
        if root.left: 
            self.sumhelper(root.left,targetSum,sum1+root.left.val)
        if root.right:
            self.sumhelper(root.right,targetSum,sum1+root.right.val)
        

如果不调用新的函数的话,那么return的就是直接需要的结果

# 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 hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
        if not root:
            return False
        if not root.left and not root.right:
            return targetSum == root.val
        return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val)

思路, 用一个list去存 进入递归的这个点到它不同的父节点的所有不同的值,然后判断sum是不是等于这个list里面的值,是的话加一

方法1:

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> int:
        self.sum = sum
        self.count = 0
        self.dfs(root,[])
        return self.count
    def dfs(self,root, sumlist):
        if root is None:
            return 0
        
        sumlist = [num+root.val for num in sumlist]
        sumlist.append(root.val)
        
        for num in sumlist:
            if num == self.sum:
                self.count += 1
        # count = sumlist.count(sum)
        self.dfs(root.left,sumlist)
        self.dfs(root.right, sumlist)


return的值要的就是计算出来的路径数量总和 

dfs是O(n)的复杂度,子节点的深度平均O(logn)的话,数组生产的复杂度是O(logn)。总的时间复杂度就是O(nlogn)把

时间,O(N)

空间复杂度O(N^2)

方法2:

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> int:
        self.sum = sum
        return self.dfs(root,[])
    def dfs(self,root, sumlist):
        if root is None:
            return 0
        
        sumlist = [num+root.val for num in sumlist]
        sumlist.append(root.val)
        
        count = 0
        for num in sumlist:
            if num == self.sum:
                count += 1
        # count = sumlist.count(sum)

        return count + self.dfs(root.left, sumlist) + self.dfs(root.right, sumlist)


思路:用主函数去回溯主树的子树

一个函数去判断子树是不是和给的树相等

# 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 isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        if not root and not subRoot:
            return True
        if not root or not subRoot:
            return False
        return self.isSametree(root,subRoot) or self.isSubtree(root.left,subRoot) or self.isSubtree(root.right,subRoot)
    def isSametree(self,s,t):
        if not s and not t:
            return True
        if not s or not t:
            return False
        return s.val == t.val and self.isSametree(s.left,t.left) and self.isSametree(s.right,t.right)

 

# 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 isSymmetric(self, root: TreeNode) -> bool:
        if not root:
            return True
        return self.isSymmetrichelper(root.left,root.right)
    def isSymmetrichelper(self,left,right):
        if not left and not right:
            return True
        if not left or not right:
            return False
        return left.val == right.val and self.isSymmetrichelper(left.right,right.left) and self.isSymmetrichelper(left.left,right.right)
            

Pre-order 前序:根左右

In-order  中序: 左根右

Post-order 后序:左右根

注意叶子节点的定义:

 叶子左右都没有子节点

# 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 minDepth(self, root: TreeNode) -> int:
        self.depth = 100000
        if not root:
            return 0
        return self.minDepthhelper(root,1)
    def minDepthhelper(self,root,depth):
        if not root.left and not root.right:
            self.depth = depth
            return depth
        if depth > self.depth:
            return depth
        if not root.left:
            return self.minDepthhelper(root.right,depth+1)
        if not root.right:
            return self.minDepthhelper(root.left,depth+1)
        return min(self.minDepthhelper(root.left,depth+1),self.minDepthhelper(root.right,depth+1))

每次计算的时候一定要自己想例子按照代码肉眼debug一遍

# 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 sumOfLeftLeaves(self, root: TreeNode) -> int:
        if not root:
            return 0
        if root.left:
            if not root.left.left and not root.left.right:
                return root.left.val + self.sumOfLeftLeaves(root.right)
        return self.sumOfLeftLeaves(root.right) + self.sumOfLeftLeaves(root.left)

问题代码: 

# 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 longestUnivaluePath(self, root: TreeNode) -> int:
        self.ans = 0
        self.maxrootpath(root)
        return self.ans
    def maxrootpath(self,root):
        if not root:
            return 
        left = self.maxrootpath(root.left)
        right = self.maxrootpath(root.right)
        left += 1 if root.left and root.left.val == root.val else 0
        right += 1 if root.right and root.right.val == root.val else 0
        self.ans = max(self.ans, left+right)
        return left+right

问题:

1.

调用maxrootpath的时候left+right是计算出的经过当前根节点的最长路径

但return的值一定是经过当前节点的最深路径

2.

left = left + 1 if root.left and root.left.val == root.val else 0
right = right + 1 if root.right and root.right.val == root.val else 0

如果值不相等的话是直接置0

正确代码:

# 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 longestUnivaluePath(self, root: TreeNode) -> int:
        self.ans = 0
        self.maxrootpath(root)
        return self.ans
    def maxrootpath(self,root):
        if not root:
            return 0
        left = self.maxrootpath(root.left)
        right = self.maxrootpath(root.right)
        left = left + 1 if root.left and root.left.val == root.val else 0
        right = right + 1 if root.right and root.right.val == root.val else 0
        self.ans = max(self.ans, left+right)
        return max(left,right)

 动态规划+二叉树

# 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 rob(self, root: TreeNode) -> int:
        #动态规划,从下到上:
        return max(self.robhelp(root))

    def robhelp(self,root):
        if not root: return 0,0 #偷,不偷
        left = self.robhelp(root.left)
        right = self.robhelp(root.right)
        #偷当前节点,则子节点不能偷
        v1 = root.val + left[1]+right[1]
        #不偷当前节点,则取左右子树偷与不偷算下来的最大值加起来
        v2 = max(left)+max(right)
        return v1,v2

用一个set去存储值。

去掉最小值,剩下的那个就是第二小值 

# 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
import heapq
class Solution:
    def findSecondMinimumValue(self, root: TreeNode) -> int:
        self.res = set()
        if not root:
            return -1
        self.helper(root)
        if len(self.res) < 2:
            return -1
        self.res.remove(min(self.res))
        return min(self.res)
    def helper(self,root):
        if len(self.res) > 3:
            return
        if not root:
            return
        self.res.add(root.val)
        self.helper(root.left)
        self.helper(root.right)

# 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 averageOfLevels(self, root: TreeNode) -> List[float]:
        self.sum = []
        self.count = []
        self.addlevel(root,0)
        for i in range(len(self.sum)):
            self.sum[i] = self.sum[i]/self.count[i]
        return self.sum

    def addlevel(self,pnode,level):
        if not pnode:
            return
        if level < len(self.sum):
            self.sum[level] += pnode.val
            self.count[level] += 1
        else:
            self.sum.append(pnode.val)
            self.count.append(1)
        self.addlevel(pnode.left,level+1)
        self.addlevel(pnode.right,level+1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值