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 ans49
二叉树的最近公共祖先。
简单递归。
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 None48
路径总和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 ans44
二叉搜索树中第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 True42
将有序数组转为二叉平衡搜索树。
挑出中间的数,简单递归。
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