827 words
4 minutes
日拱两卒(六)
2026-07-28

50#

二叉树中的最大路径和。

维护每个节点的左右两条链。

因为有负数,注意和零比较。

class Solution:
def maxPathSum(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
N = 3 * 10000 + 10
ans = -N * 1000
s = dict()
def dfs(u):
nonlocal ans
if u.left is None:
s[(u, 0)] = 0
if u.right is None:
s[(u, 1)] = 0
if u.left:
dfs(u.left)
s[(u, 0)] = max(0, max(s[(u.left, 0)], s[(u.left, 1)]) + u.left.val)
if u.right:
dfs(u.right)
s[(u, 1)] = max(0, max(s[(u.right, 0)], s[(u.right, 1)]) + u.right.val)
ans = max(ans, u.val + s[(u, 0)] + s[(u, 1)])
dfs(root)
return ans

49#

二叉树的最近公共祖先。

简单递归。

class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root is None or root == p or root == q:
return root
l = self.lowestCommonAncestor(root.left, p, q)
r = self.lowestCommonAncestor(root.right, p, q)
if l and r:
return root
if l:
return self.lowestCommonAncestor(l, p, q)
if r:
return self.lowestCommonAncestor(r, p, q)
return None

48#

路径总和III。

求路径和等于Target的路径数。这里的路径只向下。

class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:
def getSum(root, target) -> int:
if root is None:
return 0
res = 0
if root.val == target:
res += 1
res += getSum(root.left, target - root.val)
res += getSum(root.right, target - root.val)
return res
if root is None:
return 0
return getSum(root, targetSum) + self.pathSum(root.left, targetSum) + self.pathSum(root.right, targetSum)

47#

从前序与中序遍历序列构造二叉树。

这个初见不会,甚至完全不知道怎么做。

通过看前序的第一个元素能找到根,在中序里找到这个元素,那么就知道了左子树和右子树的大小。

然后就去递归解子问题。

好巧妙,我的脑子好僵化。

class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder:
return None
left_cnt = inorder.index(preorder[0])
left = self.buildTree(preorder[1: 1 + left_cnt], inorder[:left_cnt])
right = self.buildTree(preorder[1 + left_cnt:], inorder[1 + left_cnt:])
return TreeNode(preorder[0], left, right)

46#

二叉树展开为链表。

右左根遍历从后往前构造。不要忘记把左指针置空。

class Solution:
def flatten(self, root: Optional[TreeNode]) -> None:
if root is None:
return
end = None
def dfs(cur):
nonlocal end
if cur.right:
dfs(cur.right)
if cur.left:
dfs(cur.left)
cur.right = end
cur.left = None
end = cur
dfs(root)

45#

二叉树的右视图。

按深度遍历,每一层的最右边是答案。

class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
ans = []
def dfs(root, depth):
if root is None:
return
if len(ans) > depth:
ans[depth] = root.val
else:
ans.append(root.val)
dfs(root.left, depth + 1)
dfs(root.right, depth + 1)
dfs(root, 0)
return ans

44#

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

按子树大小来筛。

题解更简单,二叉搜索树的中序遍历是一个递增序列,其实就是求中序遍历的第K个元素。

class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
@cache
def sz(cur) -> int:
if cur is None:
return 0
sz_left = sz(cur.left)
sz_right = sz(cur.right)
return 1 + sz_left + sz_right
sz(root)
def dfs(cur, k) -> int:
sz_left = sz(cur.left)
if k == sz_left + 1:
return cur.val
elif k <= sz_left:
return dfs(cur.left, k)
elif k > sz_left + 1:
return dfs(cur.right, k - sz_left - 1)
return dfs(root, k)

43#

验证二叉搜索树。

昨晚上面那道题就知道这里可以检查中序遍历。

class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
check = []
def dfs(cur):
if cur is None:
return
dfs(cur.left)
check.append(cur.val)
dfs(cur.right)
dfs(root)
for i in range(len(check) - 1):
if check[i] >= check[i + 1]:
return False
return True

42#

将有序数组转为二叉平衡搜索树。

挑出中间的数,简单递归。

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

41#

二叉树的层序遍历。

按层级输出。

class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
ans = []
def dfs(cur, dep):
if cur is None:
return
if dep >= len(ans):
ans.append([cur.val])
else:
ans[dep].append(cur.val)
dfs(cur.left, dep + 1)
dfs(cur.right, dep + 1)
dfs(root, 0)
return ans