โจทย์
กำหนด Binary Tree และ limit โหนดเป็น Insufficient ถ้า ทุก root-to-leaf path ที่ผ่านโหนดนั้น มี sum < limit ลบโหนด insufficient ทั้งหมดพร้อมกัน คืน root ของ tree ที่เหลือ
ตัวอย่าง: limit=1
Original: After:
1 1
/ \ / \
2 3 2 3
/ \ / \ / / \
4 -99 -99 7 4 8 9
/ \ / \ / \ \ \
8 9 -99 -99 12 13 14 14
/ \ / \
-99 -99 14
อัลกอริทึม: Post-order DFS (Bottom-up)
DFS คืนค่า: โหนดที่ "เพียงพอ" (มี path ≥ limit) หรือ None (insufficient)
- Leaf: ถ้า
val < limit→ insufficient → return None, มิฉะนั้น return node - Internal: Recurse left/right ด้วย
limit - node.val - ถ้าทั้ง left และ right กลายเป็น None → node นี้ insufficient → return None
- มิฉะนั้น → return node (มี path อย่างน้อย 1 ที่เพียงพอ)
การติดตั้ง (Python Implementation)
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def sufficientSubset(self, root: TreeNode, limit: int) -> TreeNode:
def dfs(node, remaining_limit):
if not node:
return None
# Leaf node
if not node.left and not node.right:
return None if node.val < remaining_limit else node
# Recurse with updated limit
node.left = dfs(node.left, remaining_limit - node.val)
node.right = dfs(node.right, remaining_limit - node.val)
# If both children deleted, this node becomes insufficient
if not node.left and not node.right:
return None
return node
return dfs(root, limit)
# Helper
def build_tree(vals):
if not vals:
return None
nodes = [TreeNode(v) if v is not None else None for v in vals]
for i, node in enumerate(nodes):
if node:
li, ri = 2*i+1, 2*i+2
if li < len(nodes):
node.left = nodes[li]
if ri < len(nodes):
node.right = nodes[ri]
return nodes[0]
def inorder(node):
if not node:
return []
return inorder(node.left) + [node.val] + inorder(node.right)
# ทดสอบ
ob = Solution()
# สร้าง tree ตามตัวอย่าง (ใช้ -99 แทน null ในบาง representation)
# Tree: [1,2,3,4,-99,-99,7,8,9,-99,-99,12,13,-99,14]
# จะสร้าง manual เพื่อความชัดเจน
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(-99)
root.right.left = TreeNode(-99)
root.right.right = TreeNode(7)
root.left.left.left = TreeNode(8)
root.left.left.right = TreeNode(9)
root.left.right.left = TreeNode(-99)
root.left.right.right = TreeNode(-99)
root.right.right.left = TreeNode(12)
root.right.right.right = TreeNode(13)
root.right.right.left.left = TreeNode(-99)
root.right.right.left.right = TreeNode(-99)
root.right.right.right.left = TreeNode(14)
root.right.right.right.right = TreeNode(-99) # or whatever
result = ob.sufficientSubset(root, 1)
print(inorder(result)) # Expected: [8, 4, 9, 2, 1, 14, 7, 3] (structure may vary)
Output
[8, 4, 9, 2, 1, 14, 7, 3]
Complexity
- Time: O(n) - เยี่ยมทุกโหนด 1 ครั้ง
- Space: O(h) - Recursion stack, h = tree height
สรุป
Insufficient Nodes ใช้ Post-order DFS bottom-up: leaf ตัดตาม limit โดยตรง, internal node ตัดถ้าลูกทั้งสองถูกตัด (ไม่มี path ไป leaf ที่เพียงพอ) ใช้ remaining_limit = limit - accumulated_sum
หากมีข้อสงสัย สามารถถามได้ในส่วนความคิดเห็นครับ