|
88 | 88 | },
|
89 | 89 | {
|
90 | 90 | "cell_type": "code",
|
91 |
| - "execution_count": 15, |
| 91 | + "execution_count": null, |
92 | 92 | "metadata": {},
|
93 | 93 | "outputs": [],
|
94 | 94 | "source": [
|
|
123 | 123 | " \n",
|
124 | 124 | " return root\n",
|
125 | 125 | "\n",
|
126 |
| - "# Finding the duplicate\n", |
127 |
| - "def find_duplicate(root):\n", |
128 |
| - " visited = set()\n", |
129 |
| - " closest_duplicate = None \n", |
130 |
| - " min_depth = float('inf') # Setting minimum depth infinite as any valid depth in the tree will be smaller than infinity\n", |
| 126 | + "def dfs(node, depth, visited):\n", |
| 127 | + " if node is None:\n", |
| 128 | + " return None, float('inf') # No duplicate, infinite depth\n", |
131 | 129 | "\n",
|
132 |
| - " def dfs(node, depth):\n", |
133 |
| - " nonlocal closest_duplicate, min_depth\n", |
134 |
| - " \n", |
135 |
| - " if node is None:\n", |
136 |
| - " return\n", |
137 |
| - " \n", |
138 |
| - " if node.val in visited:\n", |
139 |
| - " if depth < min_depth: \n", |
140 |
| - " closest_duplicate = node.val\n", |
141 |
| - " min_depth = depth\n", |
142 |
| - " else:\n", |
143 |
| - " visited.add(node.val)\n", |
| 130 | + " # If the node's value has already been visited, it's a duplicate\n", |
| 131 | + " if node.val in visited:\n", |
| 132 | + " return node.val, depth # Found a duplicate at this depth\n", |
| 133 | + " \n", |
| 134 | + " visited.add(node.val)\n", |
| 135 | + "\n", |
| 136 | + " # Recurse on left and right children and return the closest duplicate\n", |
| 137 | + " left_val, left_depth = dfs(node.left, depth + 1, visited)\n", |
| 138 | + " right_val, right_depth = dfs(node.right, depth + 1, visited)\n", |
| 139 | + "\n", |
| 140 | + " # Compare which duplicate is closer to the root\n", |
| 141 | + " if left_depth < right_depth:\n", |
| 142 | + " return left_val, left_depth\n", |
| 143 | + " else:\n", |
| 144 | + " return right_val, right_depth\n", |
144 | 145 | "\n",
|
145 |
| - " dfs(node.left, depth + 1)\n", |
146 |
| - " dfs(node.right, depth + 1)\n", |
147 | 146 | "\n",
|
148 |
| - " dfs(root, 0)\n", |
| 147 | + "def find_duplicate(root):\n", |
| 148 | + " visited = set() # To track visited node values\n", |
| 149 | + " closest_duplicate, min_depth = dfs(root, 0, visited)\n", |
149 | 150 | " \n",
|
150 |
| - " return closest_duplicate if closest_duplicate is not None else -1\n" |
| 151 | + " # Return the closest duplicate if found, otherwise return -1\n", |
| 152 | + " return closest_duplicate if closest_duplicate is not None else -1\n", |
| 153 | + "\n" |
151 | 154 | ]
|
152 | 155 | },
|
153 | 156 | {
|
154 | 157 | "cell_type": "code",
|
155 |
| - "execution_count": 16, |
| 158 | + "execution_count": 21, |
156 | 159 | "metadata": {},
|
157 | 160 | "outputs": [
|
158 | 161 | {
|
|
172 | 175 | },
|
173 | 176 | {
|
174 | 177 | "cell_type": "code",
|
175 |
| - "execution_count": 17, |
176 |
| - "metadata": {}, |
177 |
| - "outputs": [ |
178 |
| - { |
179 |
| - "name": "stdout", |
180 |
| - "output_type": "stream", |
181 |
| - "text": [ |
182 |
| - "Duplicate value: -1\n" |
183 |
| - ] |
184 |
| - } |
185 |
| - ], |
186 |
| - "source": [ |
187 |
| - "example_roots = [10, 9, 8, 7] # Testing the example 2\n", |
188 |
| - "root = build_tree(example_roots)\n", |
189 |
| - "duplicate = find_duplicate(root)\n", |
190 |
| - "print(f\"Duplicate value: {duplicate}\") " |
191 |
| - ] |
192 |
| - }, |
193 |
| - { |
194 |
| - "cell_type": "code", |
195 |
| - "execution_count": 18, |
| 178 | + "execution_count": 22, |
196 | 179 | "metadata": {},
|
197 | 180 | "outputs": [
|
198 | 181 | {
|
199 | 182 | "name": "stdout",
|
200 | 183 | "output_type": "stream",
|
201 | 184 | "text": [
|
202 |
| - "Duplicate value: 10\n" |
| 185 | + "Duplicate value: 12\n" |
203 | 186 | ]
|
204 | 187 | }
|
205 | 188 | ],
|
|
212 | 195 | },
|
213 | 196 | {
|
214 | 197 | "cell_type": "code",
|
215 |
| - "execution_count": 19, |
| 198 | + "execution_count": 17, |
216 | 199 | "metadata": {},
|
217 | 200 | "outputs": [
|
218 | 201 | {
|
|
0 commit comments