class Node: def __init__(self, val): self.val = val self.left = None self.right = None def top_view(root): if not root: return [] from collections import deque q = deque([(root, 0)]) hd_node = {} min_hd = max_hd = 0 while q: node, hd = q.popleft() if hd not in hd_node: hd_node[hd] = node.val min_hd = min(min_hd, hd) max_hd = max(max_hd, hd) if node.left: q.append((node.left, hd - 1)) if node.right: q.append((node.right, hd + 1)) return [hd_node[i] for i in range(min_hd, max_hd + 1)] root = Node(1) root.left = Node(2) root.right = Node(3) root.left.right = Node(4) root.left.right.right = Node(5) root.left.right.right.right = Node(6) print(top_view(root))
The top view prints nodes visible from above. We track horizontal distances (hd) from root (hd=0). Left child decreases hd by 1, right child increases hd by 1. For each hd, the first node encountered in level order is included.
Nodes at hd -1: 2, hd 0: 1, hd 1: 3, hd 2: 6 (since 4 and 5 are hidden behind 2 and 3).
Horizontal distance is a measure of how far left or right a node is from the root. Left child decreases hd by 1, right child increases hd by 1. This helps identify nodes visible from the top.
def top_view(root): if not root: return [] from collections import deque q = deque([(root, 0)]) hd_node = {} while q: node, hd = q.pop() if hd not in hd_node: hd_node[hd] = node.val if node.left: q.append((node.left, hd - 1)) if node.right: q.append((node.right, hd + 1)) return [hd_node[i] for i in sorted(hd_node)] root = Node(1) root.left = Node(2) root.right = Node(3) print(top_view(root))
The code uses q.pop() which removes from the right end (stack behavior), but nodes are added to the right end. This causes nodes to be processed in reverse order and eventually the queue becomes empty prematurely causing IndexError.
class Node: def __init__(self, val): self.val = val self.left = None self.right = None def top_view(root): if not root: return [] from collections import deque q = deque([(root, 0)]) hd_node = {} min_hd = max_hd = 0 while q: node, hd = q.popleft() if hd not in hd_node: hd_node[hd] = node.val min_hd = min(min_hd, hd) max_hd = max(max_hd, hd) if node.left: q.append((node.left, hd - 1)) if node.right: q.append((node.right, hd + 1)) return [hd_node[i] for i in range(min_hd, max_hd + 1)] root = Node(10) root.left = Node(20) root.right = Node(30) root.left.left = Node(40) root.left.left.right = Node(70) root.right.left = Node(50) root.right.right = Node(60) root.right.right.right = Node(80) print(top_view(root))
Horizontal distances: 40 at -2, 20 at -1, 10 at 0, 30 at 1, 60 at 2, 80 at 3. Nodes 70 and 50 are hidden behind others at their horizontal distances.
Level order traversal visits nodes level by level from top to bottom. This ensures the first node encountered at each horizontal distance is the topmost node visible from above.
