遍历
2020/10/17
144. 二叉树的前序遍历
递归
# 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 traversal(self,node,result):
if(node==None):
return
else:
result.append(node.val)
self.traversal(node.left,result)
self.traversal(node.right,result)
def preorderTraversal(self, root: TreeNode) -> List[int]:
result=[]
self.traversal(root,result)
return result
非递归
- 如果不加# if (root !=None):的判断 前面要考虑 if (root==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 preorderTraversal(self, root: TreeNode) -> List[int]:
if (root==None):
return []
result=[]
stack=[root]
while(stack):
root=stack.pop()
# if (root !=None):
result.append(root.val)
if (root.right != None):
stack.append(root.right)
if (root.left != None):
stack.append(root.left)
return result
145. 二叉树的后序遍历
# 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 traversal(self,node,result):
if(node==None):
return
else:
self.traversal(node.left,result)
self.traversal(node.right,result)
result.append(node.val)
def postorderTraversal(self, root: TreeNode) -> List[int]:
result=[]
self.traversal(root,result)
return result
2020/10/18 层次遍历
637. 二叉树的层平均值
层次遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
if root is None:
return []
result=[]
nodes=[root]
sum_=0
count=0
while(nodes):
temp=[]
for node in nodes:
count+=1
sum_+=node.val
if(node.left!=None):
temp.append(node.left)
if(node.right!=None):
temp.append(node.right)
result.append(sum_/count)
nodes=temp
sum_=0
count=0
return result
- 在换层的时候 也可以不使用new一个list 直接遍历len(nodes) 把前len个Node遍历 取值 取孩子 删掉 即可 这样只需要一个List
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
if root is None:
return []
result=[]
nodes=[root]
sum_=0
while(nodes):
count=len(nodes)
# nodes list的前count个是上一层的结点
for i in range(0,count):
node=nodes[0]
sum_+=node.val
if(node.left!=None):
nodes.append(node.left)
if(node.right!=None):
nodes.append(node.right)
del nodes[0]
result.append(sum_/count)
sum_=0
return result
- Python知识点:官方用的队列 queue = collections.deque([root]) queue.popleft()
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]:
averages = list()
queue = collections.deque([root])
while queue:
total = 0
size = len(queue)
for _ in range(size):
node = queue.popleft()
total += node.val
left, right = node.left, node.right
if left:
queue.append(left)
if right:
queue.append(right)
averages.append(total / size)
return averages
513. 找树左下角的值
- 用队列
- 先加右孩子 再加左孩子 保证最后的是左下角
巧妙!
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
queue = collections.deque([root])
while(queue):
root=queue.popleft()
if(root.right):
queue.append(root.right)
if(root.left):
queue.append(root.left)
return root.val
二叉查找树
2020/10/24
669. 修剪二叉搜索树
# 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 trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
if root==None:
return None
if(root.val<low):
return self.trimBST(root.right,low,high)
if(root.val>high):
return self.trimBST(root.left,low,high)
root.left=self.trimBST(root.left,low,high)
root.right=self.trimBST(root.right,low,high)
return root
230. 二叉搜索树中第K小的元素
递归 中序遍历 计数 找到第k个就终止
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
self.cnt=0
self.val=0
self.inOrder(root,k)
return self.val
#中序遍历 获取root为根的树的第k个值
def inOrder(self,root: TreeNode, k: int):
if(root!=None):
if(root.left!=None):
self.inOrder(root.left,k)
self.cnt+=1
if(self.cnt==k):
self.val=root.val
return
if(root.right!=None):
self.inOrder(root.right,k)
官方给的递归 先中序遍历搜到所有的值,然后按照k-1的index返回元素
class Solution:
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
def inorder(r):
return inorder(r.left) + [r.val] + inorder(r.right) if r else []
return inorder(root)[k - 1]
官方给的迭代,还没看太懂 先走到最后一层 每次把最左下角的压到栈
class Solution:
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
stack = []
while True:
while root:
stack.append(root)
root = root.left
root = stack.pop()
k -= 1
if not k:
return root.val
root = root.right
538. 把二叉搜索树转换为累加树
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
self.total=0
self.dfs(root)
return root
def dfs(self,root):
if(root):
self.dfs(root.right)
self.total+=root.val
root.val=self.total
self.dfs(root.left)
2020/10/31
235. 二叉搜索树的最近公共祖先
遍历找到分叉点
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
#遍历
#print(root)
if(root == None):
return None
else:
maxNode=max(p.val,q.val)
minNode=min(p.val,q.val)
while(root):
if(root.val>maxNode):
root=root.left
else:
if(root.val<minNode):
root=root.right
else:
return root
递归
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
#递归
if(root==None):
return None
maxNode=max(p.val,q.val)
minNonde=min(p.val,q.val)
if(root.val>maxNode):
return self.lowestCommonAncestor(root.left,p,q)
if(root.val<minNonde):
return self.lowestCommonAncestor(root.right,p,q)
return root
108. 将有序数组转换为二叉搜索树
递归 想到思路 就是写不出来。。。
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root=self.getMedNode(nums,0,len(nums)-1)
return root
#返回中间节点
def getMedNode(self,nums,startIndex,endIndex):
if(endIndex<startIndex):
return None
medIndex=int((startIndex+endIndex)/2)
node=TreeNode(nums[medIndex])
node.left=self.getMedNode(nums,startIndex,medIndex-1)
node.right=self.getMedNode(nums,medIndex+1,endIndex)
return node
2020/11/11
109. 有序链表转换二叉搜索树
class Solution:
def sortedListToBST(self, head: ListNode) -> TreeNode:
if(not head):
return None
if(not head.next):
return TreeNode(head.val)
preMid=self.preMid(head)
midRight=preMid.next#中点+右边
preMid.next=None#断开原head链表
mid=TreeNode(midRight.val)
mid.left=self.sortedListToBST(head)
mid.right=self.sortedListToBST(midRight.next)
return mid
def preMid(self,head):
pre=head
slow=head
fast=head.next
while(fast.next and fast.next.next):
pre=slow
slow=slow.next
fast=fast.next.next
return pre
653. 两数之和 IV - 输入 BST
from collections import Counter
class Solution:
def findTarget(self, root: TreeNode, k: int) -> bool:
result=[]
self.dfs(root,result)#先遍历找到node值的集合
c = dict(Counter(result))#字典
for node in c.keys():
#注意k-node不能等于node
if(k-node!=node) and ((k-node) in c.keys()):
return True
return False
def dfs(self,node,result):
if(not node):
return
self.dfs(node.left,result)
result.append(node.val)
self.dfs(node.right,result)
530. 二叉搜索树的最小绝对差
先弄成排序集合 再遍历
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
valList=[]
self.dfs(root,valList)
minDiff=0
for i in range(0,len(valList)-1):
if(i==0):
minDiff=valList[i+1]-valList[i]
else:
minDiff=min(minDiff,valList[i+1]-valList[i])
return minDiff
def dfs(self,root,valList):
if(not root):
return
self.dfs(root.left,valList)
valList.append(root.val)
self.dfs(root.right,valList)
直接在遍历的时候比较最小值 少了一次遍历数组
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
self.minDiff=float('inf')
self.pre=-1
self.dfs(root)
return self.minDiff
def dfs(self,root):
if(not root):
return
self.dfs(root.left)
if(self.pre!=-1):
self.minDiff=min(self.minDiff,root.val-self.pre)
self.pre=root.val
self.dfs(root.right)
2020/11/13
501. 二叉搜索树中的众数
不能使用额外存储空间
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
self.preNode=None
self.maxCnt=1
self.curCnt=1
result=[]
self.dfs(root,result)
return result
#中序遍历 比较每个值与前一节点的值
def dfs(self,root,result):
if(not root):
return
self.dfs(root.left,result)
#更新curCnt
if(self.preNode):
if(root.val==self.preNode.val):
self.curCnt+=1
else:
self.curCnt=1
#将当前节点赋给preNode
self.preNode=root
#比较curCnt和maxCnt
if(self.curCnt==self.maxCnt):
result.append(root.val)
if(self.curCnt>self.maxCnt):
result.clear()
result.append(root.val)
self.maxCnt=self.curCnt
self.dfs(root.right,result)
递归
2020/11/15
104. 二叉树的最大深度
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if(root==None):
return 0
else:
return max(self.maxDepth(root.left),self.maxDepth(root.right))+1
110. 平衡二叉树
自顶向下 复杂度o(n^2)
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
if(root==None):
return True
if(abs(self.maxDepth(root.left)-self.maxDepth(root.right))<=1):
if(self.isBalanced(root.left) and self.isBalanced(root.right)):
return True
return False
#获取root的高度
def maxDepth(self,root):
if(root==None):
return 0
else:
return max(self.maxDepth(root.left),self.maxDepth(root.right))+1
自下向上 o(n)
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
if(self.height(root)!=-1):
return True
else:
return False
#root平衡 返回高度,不平衡返回-1
def height(self,root):
if(root==None):
return 0
leftHeight=self.height(root.left)
rightHeight=self.height(root.right)
if(leftHeight==-1 or rightHeight==-1 or abs(leftHeight-rightHeight)>1):
return -1
else:
return max(leftHeight,rightHeight)+1
2020/11/17
543. 二叉树的直径
自己写的 太臃肿了
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
if(root==None):
return 0
self.maxLength=0
def dfs(root):
if(root==None):
return
dfs(root.left)
dfs(root.right)
leftHeight=self.getHeight(root.left)
rightHeight=self.getHeight(root.right)
self.maxLength=max(self.maxLength,leftHeight+rightHeight)
dfs(root)
return self.maxLength
def getHeight(self,root:TreeNode)->int:
if(root==None):
return 0
return max(self.getHeight(root.left),self.getHeight(root.right))+1
递归只返回高度 返回之前更新全局变量
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.maxLength=0
self.getHeight(root)
return self.maxLength
def getHeight(self,root:TreeNode)->int:
if(root==None):
return 0
leftHeight=self.getHeight(root.left)
rightHeight=self.getHeight(root.right)
self.maxLength=max(self.maxLength,leftHeight+rightHeight)
return max(leftHeight,rightHeight)+1
226. 翻转二叉树
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if(root==None):
return None
self.dfs(root)
return root
def dfs(self,root):
if(root==None):
return
self.dfs(root.left)
self.dfs(root.right)
temp=root.left
root.left=root.right
root.right=temp
自己这个相当于
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if(root==None):
return None
self.invertTree(root.left)
self.invertTree(root.right)
temp=root.left
root.left=root.right
root.right=temp
return root
官方给的
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if(root==None):
return None
left=root.left
root.left=self.invertTree(root.right)
root.right=self.invertTree(left)
return root
2020/11/20
617. 合并二叉树
class Solution:
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
if(t1==None and t2==None):
return None
if(t1==None and t2!=None):
return t2
if(t1!=None and t2==None):
return t1
node=TreeNode(t1.val+t2.val)
node.left=self.mergeTrees(t1.left,t2.left)
node.right=self.mergeTrees(t1.right,t2.right)
return node
112. 路径总和
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if(root==None):
return False
if(root.left==None and root.right==None and root.val==sum):
return True
# self.hasPathSum(root.left,sum-root.val)
# self.hasPathSum(root.right,sum-root.val)
return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right,sum-root.val)
这样写为啥不对呢 是因为导致每一个节点时都会有:
- f(root.left)
- f(root.right)
- return fasle 某个子节点直接返回false了
所以可以套一个函数 让每个子节点修改全局变量的值 不要让子节点直接返回false
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if(root==None):
return
if(root.left==None and root.right==None and root.val==sum):
return True
self.hasPathSum(root.left,sum-root.val)
self.hasPathSum(root.right,sum-root.val)
return False
#改成这样就ok了
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
self.flag=False
self.dfs(root,sum)
return self.flag
def dfs(self,root,sum):
if(root==None):
return
if(root.left==None and root.right==None and root.val==sum):
self.flag=True
self.dfs(root.left,sum-root.val)
self.dfs(root.right,sum-root.val)
437. 路径总和 III
自己这个运行时间很长
每个节点有个sumlist 它等于这里面的任意一个就+1 注意用deepcopy
不然right的list就就变成left的list更新之后的了(应该是并行的)
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> int:
self.count=0
self.path(root,[sum])
return self.count
import copy
# def path(self,root,prePath,sum):
# if(root==None):
# return
# preNum=len(prePath)
# if(root.val==sum):
# self.count+=1
# for i in range(0,preNum):
# if(prePath[i]+root.val==sum):
# self.count+=1
# prePath[i]+=root.val
# prePath.append(root.val)
# print(prePath)
# self.path(root.left,copy.deepcopy(prePath),sum)
# self.path(root.right,copy.deepcopy(prePath),sum)
def path(self,root,sumList):
if(root==None):
return
for i in range(0,len(sumList)):
if(root.val==sumList[i]):
self.count+=1
if(i>0):
sumList[i]-=root.val
sumList.append(sumList[0]-root.val)
print(sumList)
self.path(root.left,copy.deepcopy(sumList))
self.path(root.right,copy.deepcopy(sumList))
2020/11/22
572. 另一个树的子树
这题还是想不出来
- return self.isSame(s,t) or self.isSubtree(s.left,t) or self.isSubtree(s.right,t)
- 要么s和t相等,要么s.left包含t,要么s.right包含t
class Solution:
def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
if(s==None):
return False
return self.isSame(s,t) or self.isSubtree(s.left,t) or self.isSubtree(s.right,t)
# s和t是否相等
def isSame(self,s,t):
if(s==None and t==None):
return True
if(s==None or t==None):
return False
if(s.val!=t.val):
return False
return self.isSame(s.left,t.left) and self.isSame(s.right,t.right)
101. 对称二叉树
递归的题 还是写不出来 得看着别人的思路
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
#root空 对称
#root不空 左子树和右子树对称才 ok
if(root==None):
return True
return self.isSymmetric2(root.left,root.right)
#判断左子树和右子树是否对称
def isSymmetric2(self,left,right):
if(left==None and right==None):
return True
if(left==None or right==None):
return False
if(left.val != right.val):
return False
return self.isSymmetric2(left.left,right.right) and self.isSymmetric2(left.right,right.left)
111. 二叉树的最小深度
层次遍历
class Solution:
def minDepth(self, root: TreeNode) -> int:
if(root==None):
return 0
curNodes=[root]
depth=1
while(len(curNodes)>0):
temp=[]
for node in curNodes:
if(node.left==None and node.right==None):
return depth
if(node.left):
temp.append(node.left)
if(node.right):
temp.append(node.right)
depth+=1
curNodes=temp
return depth
递归 注意特殊情况
class Solution:
def minDepth(self, root: TreeNode) -> int:
if(root==None):
return 0
left=self.minDepth(root.left)
right=self.minDepth(root.right)
if(left==0 or right==0):
return left+right+1 #防止出现root没有左子树 有右子树 返回1
return min(left,right)+1
2020/11/26
404. 左叶子之和
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
if(root==None):
return 0
if(self.isLeftLeave(root.left)):
return root.left.val+self.sumOfLeftLeaves(root.right)#如果root的left是左叶子 返回[左叶子值]+[F(root.right)]
else:
return self.sumOfLeftLeaves(root.left)+self.sumOfLeftLeaves(root.right)#如果root的left不是左叶子 返回[F(root.left)]+[F(root.right)]
#判读root是不是左叶子
def isLeftLeave(self,root):
if(root==None):
return False
if(root.left==None and root.right==None):
return True
return False
687. 最长同值路径
自己写的太复杂了
class Solution:
def longestUnivaluePath(self, root: TreeNode) -> int:
if(root==None):
return 0
left=self.longestUnivaluePath(root.left)
right=self.longestUnivaluePath(root.right)
cur=max(self.singleLongWithNode(root),self.twoLongWithNode(root))
return max(cur,left,right)
#root必须在路径中的最大边数 单边
def singleLongWithNode(self,root):
if(root==None):
return 0
if(root.left==None and root.right==None):
return 0
if(root.left==None):
if(root.right.val==root.val):
return 1+self.singleLongWithNode(root.right)
else:
return 0
if(root.right==None):
if(root.left.val==root.val):
return 1+self.singleLongWithNode(root.left)
else:
return 0
#左子树和右子树都存在
leftFlag=root.left.val==root.val
rightFlag=root.right.val==root.val
if(leftFlag and not rightFlag):
return 1+self.singleLongWithNode(root.left)
if(not leftFlag and rightFlag):
return 1+self.singleLongWithNode(root.right)
if(leftFlag and rightFlag):
return max(self.singleLongWithNode(root.left),self.singleLongWithNode(root.right))+1
return 0
#root必须在路径中的最大边数 双边
def twoLongWithNode(self,root):
if(root.left and root.right):
if(root.val==root.left.val==root.right.val):
return self.singleLongWithNode(root.left)+self.singleLongWithNode(root.right)+2
return 0
官方给的
class Solution:
def longestUnivaluePath(self, root: TreeNode) -> int:
self.maxPath=0
self.longestWithNode(root)
return self.maxPath
#返回最长路径 必须带有root 单边
def longestWithNode(self,root):
if(root==None):
return 0
leftPath=0
rightPath=0
left=self.longestWithNode(root.left)
right=self.longestWithNode(root.right)
if(root.left and root.left.val==root.val and root.right and root.right.val==root.val):
self.maxPath=max(self.maxPath,left+right+2)
if(root.left and root.left.val==root.val):
leftPath=left+1
if(root.right and root.right.val==root.val):
rightPath=right+1
self.maxPath=max(leftPath,rightPath,self.maxPath)
return max(leftPath,rightPath)
2020/11/29
671. 二叉树中第二小的节点
class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
if(root==None or root.left==None):
return -1
left=self.findSecondMinimumValue(root.left)#左侧第2小
right=self.findSecondMinimumValue(root.right)#右侧第2小
# 整个树全都是一个值
if(left==right==root.left.val==root.right.val):
return -1
result=-1
temp=[]
# 有大于root的值 选大的中最小的
for x in [root.left.val,root.right.val,left,right]:
if(x>root.val):
temp.append(x)
if(len(temp)>0):
result=min(temp)
return result
2021/7/17
124. 二叉树中的最大路径和
从底向上,每个root考虑三个情况:
- 1 有root最长single path
- 2 没有root最长single path
- 3 在root这个节点最长path,包括:
- 向左single
- 向右single
- 左single+右single
关键一点是dfs要返回三个值,如果只返回前两个值,树节点[-2 -1]这种会出错,做出来是0,所以root==None时,可以返回root_max=-inf,避免了负数这种情况
class Solution:
def maxPathSum(self, root: TreeNode) -> int:
if(not root):
return 0
# 只能拐点node 连left and right
# 其他 只能连left or right
if(not root.left and not root.right):
return root.val
self.max=-float('inf')
self.dfs(root)
return self.max
# 计算root
#1 有root最长single
#2 没有root最长single
#3 root以下最长single
def dfs(self,root):
if(not root):
return 0,0,-float('inf')
left_with,left_with_out,left_max=self.dfs(root.left)
right_with,right_with_out,right_max=self.dfs(root.right)
with_max=root.val+max(0,left_with,right_with)
with_out_max=max(left_max,right_max)
root_max=max(with_max,with_out_max,root.val+left_with+right_with)
# 更新max
self.max=max(self.max,root_max)
return with_max,with_out_max,root_max
自已写的这种得区分left_with还是left_with_out,官方给的不需要:
- dfs返回root最大贡献值
- 更新root_max时,判断leftmax=max(0,left)和rightmax=max(0,right),如果孩子贡献<0,就令其为0,返回的root.val避免了<0的情况
- root_max=max(root.val,root.val+left,root.val+right)
class Solution:
def maxPathSum(self, root: TreeNode) -> int:
if(not root):
return 0
# 只能拐点node 连left and right
# 其他 只能连left or right
self.max=-float('inf')
self.dfs(root)
return self.max
# 计算root最大的single路径sum 【计算root最大贡献值】
def dfs(self,root):
if(not root):
return 0
left=max(self.dfs(root.left),0)
right=max(self.dfs(root.right),0)
# 通过这里加入root.val 避免了负数情况
root_max=max(root.val,root.val+left,root.val+right)
# 更新max
self.max=max(self.max,root_max,root.val+left+right)
return root_max
129. 求根节点到叶节点数字之和
class Solution:
def sumNumbers(self, root: TreeNode) -> int:
if(not root):
return 0
self.ret=0
self.dfs(root,0)
return self.ret
def dfs(self,root,pre):
if(not root):
return
pre=pre*10+root.val
if(not root.left and not root.right):
self.ret+=pre
self.dfs(root.left,pre)
self.dfs(root.right,pre)
199. 二叉树的右视图
注:deque 数据类型来自于collections 模块,支持从头和尾部的常数时间 append/pop 操作。若使用 Python 的 list,通过 list.pop(0) 去除头部会消耗 O(n)O(n) 的时间。
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/solution/er-cha-shu-de-you-shi-tu-by-leetcode-solution/
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
if(not root):
return []
ret=[]
stack=[root]
while(stack):
ret.append(stack[0].val)
next_stack=[]
for _ in range(len(stack)):
node=stack.pop(0)
if(node.right):
next_stack.append(node.right)
if(node.left):
next_stack.append(node.left)
stack=next_stack
return ret
337. 打家劫舍 III
class Solution:
def rob(self, root: TreeNode) -> int:
if(not root):
return 0
self.max=0
self.dfs(root)
return self.max
# 返回在root子树上的max_with max_with_out
def dfs(self,root):
if(not root):
return 0,0
left_with,left_with_out=self.dfs(root.left)
right_with,right_with_out=self.dfs(root.right)
root_with=root.val+max(0,left_with_out,right_with_out,left_with_out+right_with_out)
root_with_out=max(0,left_with,left_with_out,right_with,right_with_out,)
root_with_out=max(right_with_out,max(left_with,left_with_out)+max(right_with,right_with_out))
self.max=max(self.max,root_with,root_with_out)
return root_with,root_with_out