|
| 1 | +<h1 align='center'>Diagonal - Tree - Traversal</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Diagonal Tree Traversal](https://www.geeksforgeeks.org/problems/diagonal-traversal-of-binary-tree/1) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +## Problem Explanation |
| 12 | + |
| 13 | +In a **Diagonal Tree Traversal**, we need to print all nodes of a binary tree diagonal-wise. Nodes are considered to be on the same diagonal if they are either at the same level or shifted rightward. |
| 14 | + |
| 15 | +The diagonal traversal of a binary tree is represented by grouping nodes that share the same diagonal number. Starting from the root, all right nodes are considered to be on the same diagonal, while left children increment the diagonal by 1. |
| 16 | + |
| 17 | +#### Example: |
| 18 | +For the following binary tree: |
| 19 | +``` |
| 20 | + 8 |
| 21 | + / \ |
| 22 | + 3 10 |
| 23 | + / \ \ |
| 24 | + 1 6 14 |
| 25 | + / \ / |
| 26 | + 4 7 13 |
| 27 | +``` |
| 28 | + |
| 29 | +The diagonal traversal would yield the output: `[8, 10, 14, 3, 6, 7, 13, 1, 4]` |
| 30 | + |
| 31 | +#### Real-world Analogy: |
| 32 | +Imagine rows of seating in a movie theater where people in the same row are on the same diagonal and each step down a row increases the diagonal level. |
| 33 | + |
| 34 | +#### Edge Cases: |
| 35 | +- An empty tree should return an empty list. |
| 36 | +- Trees with only left or only right children would have each node in a new or the same diagonal, respectively. |
| 37 | + |
| 38 | +--- |
| 39 | + |
| 40 | +### Step 2: Approach |
| 41 | + |
| 42 | +#### High-Level Overview: |
| 43 | +To traverse diagonally: |
| 44 | +1. Use a map to store the nodes grouped by their diagonal levels. |
| 45 | +2. Traverse the tree recursively, increasing the diagonal level for left children and maintaining the same level for right children. |
| 46 | +3. Finally, concatenate all values from each diagonal into a single list. |
| 47 | + |
| 48 | +#### Step-by-Step Breakdown: |
| 49 | +1. Start from the root node with diagonal `0`. |
| 50 | +2. Add the node’s data to the corresponding diagonal level in the map. |
| 51 | +3. Recur to the left child with `d+1` (increment diagonal level). |
| 52 | +4. Recur to the right child with the same diagonal level `d`. |
| 53 | +5. After the traversal, read the map diagonally from left to right and append all elements to the result list. |
| 54 | + |
| 55 | +## Problem Solution |
| 56 | +```cpp |
| 57 | +void solve(Node* root, int d, map<int, vector<int>> & diagonalMap){ |
| 58 | + if(root == NULL) return; |
| 59 | + |
| 60 | + diagonalMap[d].push_back(root -> data); |
| 61 | + |
| 62 | + solve(root -> left, d + 1, diagonalMap); |
| 63 | + solve(root -> right, d, diagonalMap); |
| 64 | +} |
| 65 | +vector<int> diagonal(Node *root) |
| 66 | +{ |
| 67 | + map<int, vector<int>> diagonalMap; |
| 68 | + vector<int> result; |
| 69 | + |
| 70 | + solve(root, 0, diagonalMap); |
| 71 | + |
| 72 | + |
| 73 | + for(auto i : diagonalMap){ |
| 74 | + result.insert(result.end(), i.second.begin(), i.second.end()); |
| 75 | + } |
| 76 | + |
| 77 | + |
| 78 | + return result; |
| 79 | +} |
| 80 | +``` |
| 81 | +
|
| 82 | +## Problem Solution Explanation |
| 83 | +
|
| 84 | +```cpp |
| 85 | +void solve(Node* root, int d, map<int, vector<int>> &diagonalMap){ |
| 86 | + if(root == NULL) return; |
| 87 | + |
| 88 | + diagonalMap[d].push_back(root -> data); |
| 89 | + |
| 90 | + solve(root -> left, d + 1, diagonalMap); |
| 91 | + solve(root -> right, d, diagonalMap); |
| 92 | +} |
| 93 | +``` |
| 94 | +- **Function Definition**: `solve` is a helper function that performs the diagonal traversal recursively. |
| 95 | +- **Parameters**: |
| 96 | + - `Node* root`: The current node in the traversal. |
| 97 | + - `int d`: The diagonal level. |
| 98 | + - `map<int, vector<int>> &diagonalMap`: A map that keeps track of each diagonal level. |
| 99 | +- **Null Check**: If the current node is `NULL`, return. |
| 100 | +- **Add Node Data to Map**: Insert the node’s data in the map at the key corresponding to the current diagonal level `d`. |
| 101 | +- **Recursive Calls**: |
| 102 | + - `solve(root -> left, d + 1, diagonalMap)`: Traverse the left child, increasing the diagonal level. |
| 103 | + - `solve(root -> right, d, diagonalMap)`: Traverse the right child, keeping the diagonal level the same. |
| 104 | + |
| 105 | +```cpp |
| 106 | +vector<int> diagonal(Node *root) { |
| 107 | + map<int, vector<int>> diagonalMap; |
| 108 | + vector<int> result; |
| 109 | + |
| 110 | + solve(root, 0, diagonalMap); |
| 111 | +``` |
| 112 | +- **Initialization**: |
| 113 | + - `diagonalMap`: Stores nodes at each diagonal level. |
| 114 | + - `result`: Final output vector. |
| 115 | +- **Recursive Call**: Starts the traversal from the root at diagonal `0`. |
| 116 | +
|
| 117 | +```cpp |
| 118 | + for(auto i : diagonalMap){ |
| 119 | + result.insert(result.end(), i.second.begin(), i.second.end()); |
| 120 | + } |
| 121 | + |
| 122 | + return result; |
| 123 | +} |
| 124 | +``` |
| 125 | +- **Concatenate Diagonals**: |
| 126 | + - For each diagonal level in the map (sorted by keys), add all node values to the `result` vector. |
| 127 | + - `result.insert` appends each vector from `diagonalMap` into `result`. |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +### Step 4: Output Examples with Explanation |
| 132 | + |
| 133 | +#### Example 1: |
| 134 | +Given Tree: |
| 135 | +``` |
| 136 | + 8 |
| 137 | + / \ |
| 138 | + 3 10 |
| 139 | + / \ \ |
| 140 | + 1 6 14 |
| 141 | + / \ / |
| 142 | + 4 7 13 |
| 143 | +``` |
| 144 | + |
| 145 | +Diagonal Traversal: |
| 146 | +- **Diagonal 0**: `[8, 10, 14]` |
| 147 | +- **Diagonal 1**: `[3, 6, 7, 13]` |
| 148 | +- **Diagonal 2**: `[1, 4]` |
| 149 | + |
| 150 | +Final Output: `[8, 10, 14, 3, 6, 7, 13, 1, 4]` |
| 151 | + |
| 152 | +#### Example 2: |
| 153 | +Given Tree: |
| 154 | +``` |
| 155 | + 1 |
| 156 | + / \ |
| 157 | + 2 3 |
| 158 | +``` |
| 159 | + |
| 160 | +Diagonal Traversal: |
| 161 | +- **Diagonal 0**: `[1, 3]` |
| 162 | +- **Diagonal 1**: `[2]` |
| 163 | + |
| 164 | +Final Output: `[1, 3, 2]` |
| 165 | + |
| 166 | +--- |
| 167 | + |
| 168 | +### Step 5: Time and Space Complexity |
| 169 | + |
| 170 | +#### Time Complexity: |
| 171 | +- **O(N)**: Each node is visited once during the traversal, where **N** is the number of nodes. |
| 172 | + |
| 173 | +#### Space Complexity: |
| 174 | +- **O(N)**: Requires a map to store nodes by diagonal level, which may take up to **O(N)** space in the worst case (e.g., skewed tree). The result vector also uses **O(N)** space to store the final output. |
0 commit comments