|
| 1 | +<h1 align='center'>Top - View - of - Binary - Tree</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Top view of Binary Tree](https://www.geeksforgeeks.org/problems/top-view-of-binary-tree/1) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Problem Explanation |
| 11 | + |
| 12 | +In this problem, you need to find the **top view** of a binary tree. The top view is the set of nodes that are visible when the tree is viewed from above. If two nodes exist at the same horizontal distance from the root, only the topmost node is considered visible. |
| 13 | + |
| 14 | +For example: |
| 15 | + |
| 16 | +Given a binary tree: |
| 17 | +``` |
| 18 | + 1 |
| 19 | + / \ |
| 20 | + 2 3 |
| 21 | + / \ \ |
| 22 | + 4 5 6 |
| 23 | +``` |
| 24 | + |
| 25 | +The **top view** of this binary tree is `[4, 2, 1, 3, 6]`. |
| 26 | + |
| 27 | +### Step 2: Approach and Explanation |
| 28 | + |
| 29 | +To solve this problem, we can use the concept of **horizontal distance (HD)**: |
| 30 | +1. We start at the root node, which has an HD of 0. |
| 31 | +2. For the left child of a node, the HD decreases by 1, and for the right child, the HD increases by 1. |
| 32 | +3. We use a **queue** to process nodes in level-order (breadth-first traversal) and a **map** to store the first node encountered at each HD, which represents the topmost node at that HD. |
| 33 | + |
| 34 | +By processing nodes level-by-level and recording only the first node at each HD in the map, we capture the top view of the tree. |
| 35 | + |
| 36 | +## Problem Solution |
| 37 | +```cpp |
| 38 | +class Solution |
| 39 | +{ |
| 40 | + public: |
| 41 | + //Function to return a list of nodes visible from the top view |
| 42 | + //from left to right in Binary Tree. |
| 43 | + vector<int> topView(Node *root) |
| 44 | + { |
| 45 | + vector<int> ans; |
| 46 | + if(root == NULL) return ans; |
| 47 | + |
| 48 | + map<int, int> topNode; |
| 49 | + queue<pair<Node*, int>> q; |
| 50 | + |
| 51 | + q.push({root, 0}); |
| 52 | + |
| 53 | + while(!q.empty()){ |
| 54 | + pair<Node*, int> temp = q.front(); |
| 55 | + q.pop(); |
| 56 | + |
| 57 | + Node* frontNode = temp.first; |
| 58 | + int hd = temp.second; |
| 59 | + |
| 60 | + if(topNode.find(hd) == topNode.end()){ |
| 61 | + topNode[hd] = frontNode -> data; |
| 62 | + } |
| 63 | + |
| 64 | + if(frontNode -> left){ |
| 65 | + q.push({frontNode -> left, hd -1}); |
| 66 | + } |
| 67 | + |
| 68 | + if(frontNode -> right){ |
| 69 | + q.push({frontNode -> right, hd + 1}); |
| 70 | + } |
| 71 | + |
| 72 | + } |
| 73 | + for(auto i : topNode){ |
| 74 | + ans.push_back(i.second); |
| 75 | + } |
| 76 | + |
| 77 | + |
| 78 | + return ans; |
| 79 | + } |
| 80 | + |
| 81 | +}; |
| 82 | +``` |
| 83 | + |
| 84 | +## Problem Solution Explanation |
| 85 | + |
| 86 | +```cpp |
| 87 | +class Solution |
| 88 | +{ |
| 89 | + public: |
| 90 | + // Function to return a list of nodes visible from the top view |
| 91 | + // from left to right in Binary Tree. |
| 92 | + vector<int> topView(Node *root) |
| 93 | + { |
| 94 | +``` |
| 95 | +- Defines a class `Solution` containing the function `topView` that takes the root of the tree as input and returns a vector of integers representing the top view of the tree. |
| 96 | +
|
| 97 | +```cpp |
| 98 | + vector<int> ans; |
| 99 | + if(root == NULL) return ans; |
| 100 | +``` |
| 101 | +- Initializes an empty vector `ans` to store the top view. |
| 102 | +- If the root is `NULL`, the tree is empty, so we return `ans` as an empty vector. |
| 103 | + |
| 104 | +```cpp |
| 105 | + map<int, int> topNode; |
| 106 | + queue<pair<Node*, int>> q; |
| 107 | +``` |
| 108 | +- `topNode`: A map where the key is the horizontal distance (HD) and the value is the data of the topmost node at that HD. |
| 109 | +- `q`: A queue to perform level-order traversal, storing pairs of a node and its horizontal distance. |
| 110 | + |
| 111 | +```cpp |
| 112 | + q.push({root, 0}); |
| 113 | +``` |
| 114 | +- Adds the root node to the queue with an HD of `0`. |
| 115 | +
|
| 116 | +```cpp |
| 117 | + while(!q.empty()){ |
| 118 | + pair<Node*, int> temp = q.front(); |
| 119 | + q.pop(); |
| 120 | + |
| 121 | + Node* frontNode = temp.first; |
| 122 | + int hd = temp.second; |
| 123 | +``` |
| 124 | +- The `while` loop runs until the queue is empty. |
| 125 | +- Retrieves the front element from the queue (`temp`), which is a pair containing the node (`frontNode`) and its HD (`hd`). |
| 126 | +- Removes this element from the queue with `q.pop()`. |
| 127 | + |
| 128 | +```cpp |
| 129 | + if(topNode.find(hd) == topNode.end()){ |
| 130 | + topNode[hd] = frontNode -> data; |
| 131 | + } |
| 132 | +``` |
| 133 | +- Checks if the HD `hd` is already present in the map `topNode`. |
| 134 | +- If not, it means this is the first node encountered at this HD, so it stores the node’s data at `topNode[hd]`. |
| 135 | +
|
| 136 | +```cpp |
| 137 | + if(frontNode -> left){ |
| 138 | + q.push({frontNode -> left, hd -1}); |
| 139 | + } |
| 140 | +``` |
| 141 | +- If the current node has a left child, it is added to the queue with an HD of `hd - 1` (one unit to the left). |
| 142 | + |
| 143 | +```cpp |
| 144 | + if(frontNode -> right){ |
| 145 | + q.push({frontNode -> right, hd + 1}); |
| 146 | + } |
| 147 | +``` |
| 148 | +- If the current node has a right child, it is added to the queue with an HD of `hd + 1` (one unit to the right). |
| 149 | +
|
| 150 | +```cpp |
| 151 | + } |
| 152 | +``` |
| 153 | +- Ends the `while` loop once all nodes have been processed. |
| 154 | + |
| 155 | +```cpp |
| 156 | + for(auto i : topNode){ |
| 157 | + ans.push_back(i.second); |
| 158 | + } |
| 159 | +``` |
| 160 | +- Loops through the `topNode` map in ascending order of HD and pushes each node’s data into the `ans` vector. This ensures the nodes are ordered from leftmost to rightmost in the top view. |
| 161 | +
|
| 162 | +```cpp |
| 163 | + return ans; |
| 164 | + } |
| 165 | +}; |
| 166 | +``` |
| 167 | +- Returns the `ans` vector containing the top view of the binary tree. |
| 168 | + |
| 169 | +### Step 4: Output Examples with Explanation |
| 170 | + |
| 171 | +Given this binary tree: |
| 172 | + |
| 173 | +``` |
| 174 | + 1 |
| 175 | + / \ |
| 176 | + 2 3 |
| 177 | + / \ \ |
| 178 | + 4 5 6 |
| 179 | +``` |
| 180 | + |
| 181 | +**Horizontal Distances**: |
| 182 | +- HD `-2`: Node `4` |
| 183 | +- HD `-1`: Node `2` |
| 184 | +- HD `0`: Node `1` (root) |
| 185 | +- HD `1`: Node `3` |
| 186 | +- HD `2`: Node `6` |
| 187 | + |
| 188 | +The top view would be: `[4, 2, 1, 3, 6]`. |
| 189 | + |
| 190 | +Another example: |
| 191 | + |
| 192 | +``` |
| 193 | + 1 |
| 194 | + / \ |
| 195 | + 2 3 |
| 196 | + \ |
| 197 | + 4 |
| 198 | + \ |
| 199 | + 5 |
| 200 | + \ |
| 201 | + 6 |
| 202 | +``` |
| 203 | + |
| 204 | +Top view for this tree would be: `[2, 1, 3, 6]`. |
| 205 | + |
| 206 | +### Step 5: Time and Space Complexity |
| 207 | + |
| 208 | +#### Time Complexity |
| 209 | +- **O(N)**: Every node is processed once in the level-order traversal, so the time complexity is proportional to the number of nodes, **N**. |
| 210 | + |
| 211 | +#### Space Complexity |
| 212 | +- **O(N)**: The space required by the map `topNode` is proportional to the number of nodes. |
| 213 | +- The queue `q` also holds at most **N** nodes in the worst case. |
| 214 | + |
| 215 | +So the overall space complexity is **O(N)**. |
| 216 | + |
| 217 | +This approach captures the top view efficiently using horizontal distances and level-order traversal, ensuring only the topmost node at each HD is stored. |
0 commit comments