Đề bài: Cho cây nhị phân, tìm giá trị trung bình lớn nhất среди tất cả các subtree (cây con). Trung bình = tổng giá trị node / số node.
Ví dụ: Tree [5,6,1] (root=5, left=6, right=1). Subtree averages: node 5: (5+6+1)/3=4, node 6: 6/1=6, node 1: 1/1=1. Max = 6.
Ý tưởng: Post-order DFS Trả Về (sum, count)
Duyệt post-order (trái, phải, gốc). Tại mỗi node:
- Lấy
(left_sum, left_cnt)và(right_sum, right_cnt). total_sum = left_sum + right_sum + node.valtotal_cnt = left_cnt + right_cnt + 1- Cập nhật global max average:
max_avg = max(max_avg, total_sum / total_cnt) - Trả về
(total_sum, total_cnt)cho parent.
Code Python
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def maximumAverageSubtree(self, root: TreeNode) -> float:
self.max_avg = 0.0
def dfs(node):
if not node:
return (0, 0) # (sum, count)
left_sum, left_cnt = dfs(node.left)
right_sum, right_cnt = dfs(node.right)
total_sum = left_sum + right_sum + node.val
total_cnt = left_cnt + right_cnt + 1
self.max_avg = max(self.max_avg, total_sum / total_cnt)
return (total_sum, total_cnt)
dfs(root)
return self.max_avg
# Helper build tree
def build_tree(vals):
if not vals: return None
nodes = [TreeNode(v) if v is not None else None for v in vals]
kids = nodes[::-1]
root = kids.pop()
for node in nodes:
if node:
if kids: node.left = kids.pop()
if kids: node.right = kids.pop()
return root
# Test
root = build_tree([5,6,1])
ob = Solution()
print(ob.maximumAverageSubtree(root)) # 6.0
Phân tích
- Time:
O(n) - Space:
O(h)recursion stack. - Chỉ duyệt 1 lần, tính toán trên đường đi lên.
Lưu ý
- Giá trị node có thể âm → max_avg khởi tạo =
-infan toàn hơn. - Kết quả là float.
Kết luận
Post-order DFS累积 sum và count, cập nhật max average tại mỗi node. Pattern kinh điển cho subtree aggregate problems.