|
21 | 21 | },
|
22 | 22 | {
|
23 | 23 | "cell_type": "code",
|
24 |
| - "execution_count": null, |
| 24 | + "execution_count": 85, |
25 | 25 | "metadata": {},
|
26 |
| - "outputs": [], |
| 26 | + "outputs": [ |
| 27 | + { |
| 28 | + "name": "stdout", |
| 29 | + "output_type": "stream", |
| 30 | + "text": [ |
| 31 | + "2\n" |
| 32 | + ] |
| 33 | + } |
| 34 | + ], |
27 | 35 | "source": [
|
28 | 36 | "import hashlib\n",
|
29 | 37 | "\n",
|
30 | 38 | "def hash_to_range(input_string: str) -> int:\n",
|
31 | 39 | " hash_object = hashlib.sha256(input_string.encode())\n",
|
32 | 40 | " hash_int = int(hash_object.hexdigest(), 16)\n",
|
33 | 41 | " return (hash_int % 3) + 1\n",
|
34 |
| - "input_string = \"your_first_name_here\"\n", |
| 42 | + "input_string = \"nipun\"\n", |
35 | 43 | "result = hash_to_range(input_string)\n",
|
36 | 44 | "print(result)\n"
|
37 | 45 | ]
|
|
130 | 138 | },
|
131 | 139 | {
|
132 | 140 | "cell_type": "code",
|
133 |
| - "execution_count": null, |
| 141 | + "execution_count": 23, |
134 | 142 | "metadata": {},
|
135 | 143 | "outputs": [],
|
136 | 144 | "source": [
|
| 145 | + "# Step 1\n", |
137 | 146 | "# Definition for a binary tree node.\n",
|
138 |
| - "# class TreeNode(object):\n", |
139 |
| - "# def __init__(self, val = 0, left = None, right = None):\n", |
140 |
| - "# self.val = val\n", |
141 |
| - "# self.left = left\n", |
142 |
| - "# self.right = right\n", |
143 |
| - "def bt_path(root: TreeNode) -> List[List[int]]:\n", |
144 |
| - " # TODO" |
| 147 | + "class TreeNode(object):\n", |
| 148 | + " def __init__(self, val = 0, left = None, right = None):\n", |
| 149 | + " self.val = val\n", |
| 150 | + " self.left = left\n", |
| 151 | + " self.right = right" |
145 | 152 | ]
|
146 | 153 | },
|
147 | 154 | {
|
|
201 | 208 | ]
|
202 | 209 | },
|
203 | 210 | {
|
204 |
| - "cell_type": "code", |
205 |
| - "execution_count": null, |
206 |
| - "metadata": {}, |
207 |
| - "outputs": [], |
| 211 | + "cell_type": "raw", |
| 212 | + "metadata": { |
| 213 | + "vscode": { |
| 214 | + "languageId": "raw" |
| 215 | + } |
| 216 | + }, |
208 | 217 | "source": [
|
209 |
| - "# Your answer here" |
| 218 | + "I have a binary tree, I want to find all possible way I can get from the top (or the root node) to the bottom (leaf).\n", |
| 219 | + "Since, there are multiple leaves. I have multiple paths." |
210 | 220 | ]
|
211 | 221 | },
|
212 | 222 | {
|
|
217 | 227 | ]
|
218 | 228 | },
|
219 | 229 | {
|
220 |
| - "cell_type": "code", |
221 |
| - "execution_count": null, |
222 |
| - "metadata": {}, |
223 |
| - "outputs": [], |
| 230 | + "cell_type": "raw", |
| 231 | + "metadata": { |
| 232 | + "vscode": { |
| 233 | + "languageId": "raw" |
| 234 | + } |
| 235 | + }, |
224 | 236 | "source": [
|
225 |
| - "# Your answer here" |
| 237 | + "#Tree # 1 ->\n", |
| 238 | + "[1, 2, 3 , 4 , 5, 6 , 7]\n", |
| 239 | + "#Should return\n", |
| 240 | + "[('1', '2', '4'), ('1', '2', '5'), ('1', '3', '6'), ('1', '3', '7')]\n", |
| 241 | + "\n", |
| 242 | + "# Tree # 2\n", |
| 243 | + "[1, 2, 3, 3, 5 , 'my_Leaf']\n", |
| 244 | + "#hould return\n", |
| 245 | + "[('1', '2', '3'), ('1', '2', '5'), ('1', '3', 'my_Leaf')]" |
226 | 246 | ]
|
227 | 247 | },
|
228 | 248 | {
|
|
235 | 255 | },
|
236 | 256 | {
|
237 | 257 | "cell_type": "code",
|
238 |
| - "execution_count": null, |
| 258 | + "execution_count": 86, |
239 | 259 | "metadata": {},
|
240 | 260 | "outputs": [],
|
241 | 261 | "source": [
|
242 |
| - "# Your answer here" |
| 262 | + "# Step 2\n", |
| 263 | + "# As per the instructions, the input is a list. I have to first convert the list to a tree\n", |
| 264 | + "\n", |
| 265 | + "from collections import deque\n", |
| 266 | + "from typing import List, Optional\n", |
| 267 | + "\n", |
| 268 | + "\n", |
| 269 | + "def list_to_tree(lst: list[Optional[int]]) -> Optional[TreeNode]:\n", |
| 270 | + " if not lst or lst[0] is None:\n", |
| 271 | + " return None # Empty tree case\n", |
| 272 | + "\n", |
| 273 | + " root = TreeNode(lst[0]) # Create the root\n", |
| 274 | + " queue = deque([root]) # Queue for level-order insertion\n", |
| 275 | + " i = 1 # Index in the list\n", |
| 276 | + "\n", |
| 277 | + " while i < len(lst):\n", |
| 278 | + " node = queue.popleft() # Get the current parent node\n", |
| 279 | + "\n", |
| 280 | + " # Assign left child\n", |
| 281 | + " if i < len(lst) and lst[i] is not None:\n", |
| 282 | + " node.left = TreeNode(lst[i])\n", |
| 283 | + " queue.append(node.left)\n", |
| 284 | + " i += 1\n", |
| 285 | + "\n", |
| 286 | + " # Assign right child\n", |
| 287 | + " if i < len(lst) and lst[i] is not None:\n", |
| 288 | + " node.right = TreeNode(lst[i])\n", |
| 289 | + " queue.append(node.right)\n", |
| 290 | + " i += 1\n", |
| 291 | + "\n", |
| 292 | + " return root # Return the tree root" |
| 293 | + ] |
| 294 | + }, |
| 295 | + { |
| 296 | + "cell_type": "code", |
| 297 | + "execution_count": 87, |
| 298 | + "metadata": {}, |
| 299 | + "outputs": [ |
| 300 | + { |
| 301 | + "name": "stdout", |
| 302 | + "output_type": "stream", |
| 303 | + "text": [ |
| 304 | + "[('1', '2', '3'), ('1', '2', '5'), ('1', '2', '6'), ('1', '2', '7')]\n" |
| 305 | + ] |
| 306 | + } |
| 307 | + ], |
| 308 | + "source": [ |
| 309 | + "# Step 3: Recursive method for Depth first search \n", |
| 310 | + "def bt_path(root: TreeNode) -> list[list[int]]:\n", |
| 311 | + " # TODO\n", |
| 312 | + " def dfs(node, path, result): #base case\n", |
| 313 | + " if not node: \n", |
| 314 | + " return\n", |
| 315 | + " path.append(str(node.val)) # Append current node value to path\n", |
| 316 | + " if not node.left and not node.right: # If it's a leaf, add path to result, node.left and node.right will both return false for a leaf node\n", |
| 317 | + " #result.append(\"->\".join(path)) #End search\n", |
| 318 | + " #print(tuple(path))\n", |
| 319 | + " result.append(tuple(path))\n", |
| 320 | + " else:\n", |
| 321 | + " dfs(node.left, path[:], result) # Recursion for left subtree\n", |
| 322 | + " dfs(node.right, path[:], result) # Recursion for right subtree\n", |
| 323 | + " path.pop() # Backtrack\n", |
| 324 | + "\n", |
| 325 | + " result = []\n", |
| 326 | + " dfs(root, [], result)\n", |
| 327 | + " return result\n", |
| 328 | + "\n", |
| 329 | + "# Step 1: Convert list to binary tree\n", |
| 330 | + "tree_list = [1, 2, 2, 3, 5, 6, 7] # Example from above\n", |
| 331 | + "root = list_to_tree(tree_list)\n", |
| 332 | + "\n", |
| 333 | + "# Step 2: Run DFS to get all root-to-leaf paths\n", |
| 334 | + "paths = bt_path(root)\n", |
| 335 | + "\n", |
| 336 | + "# Step 3: Print result\n", |
| 337 | + "print(paths) # Expected Output: ['1->2->5', '1->3']" |
243 | 338 | ]
|
244 | 339 | },
|
245 | 340 | {
|
|
251 | 346 | ]
|
252 | 347 | },
|
253 | 348 | {
|
254 |
| - "cell_type": "code", |
255 |
| - "execution_count": null, |
256 |
| - "metadata": {}, |
257 |
| - "outputs": [], |
| 349 | + "cell_type": "raw", |
| 350 | + "metadata": { |
| 351 | + "vscode": { |
| 352 | + "languageId": "raw" |
| 353 | + } |
| 354 | + }, |
258 | 355 | "source": [
|
259 |
| - "# Your answer here" |
| 356 | + "# Your answer here\n", |
| 357 | + "\n", |
| 358 | + "It can be broken down into a recursive method, because a big tree is made up a smaller trees. A binary free is made up of 2 smaller trees" |
260 | 359 | ]
|
261 | 360 | },
|
262 | 361 | {
|
|
268 | 367 | ]
|
269 | 368 | },
|
270 | 369 | {
|
271 |
| - "cell_type": "code", |
272 |
| - "execution_count": null, |
273 |
| - "metadata": {}, |
274 |
| - "outputs": [], |
| 370 | + "cell_type": "raw", |
| 371 | + "metadata": { |
| 372 | + "vscode": { |
| 373 | + "languageId": "raw" |
| 374 | + } |
| 375 | + }, |
275 | 376 | "source": [
|
276 |
| - "# Your answer here" |
| 377 | + "# Your answer here\n", |
| 378 | + "\n", |
| 379 | + "Time: O(N) Because each path is traversed only once\n", |
| 380 | + "Space: O(LogN) for each path, because that is the depth of the tree\n", |
| 381 | + " There are N/2 leaves, so N possible paths\n", |
| 382 | + " O(NLog(N))" |
277 | 383 | ]
|
278 | 384 | },
|
279 | 385 | {
|
|
285 | 391 | ]
|
286 | 392 | },
|
287 | 393 | {
|
288 |
| - "cell_type": "code", |
289 |
| - "execution_count": null, |
290 |
| - "metadata": {}, |
291 |
| - "outputs": [], |
| 394 | + "cell_type": "raw", |
| 395 | + "metadata": { |
| 396 | + "vscode": { |
| 397 | + "languageId": "raw" |
| 398 | + } |
| 399 | + }, |
292 | 400 | "source": [
|
293 |
| - "# Your answer here" |
| 401 | + "# Your answer here\n", |
| 402 | + "\n", |
| 403 | + "Another method is using a stack data-structure. First understand how this DS works:\n", |
| 404 | + "\n", |
| 405 | + "A stack is a data structure that works like a stack of plates:\n", |
| 406 | + "\n", |
| 407 | + "1. You add items to the top (push).\n", |
| 408 | + "2. You remove items from the top (pop). - LIFO\n", |
| 409 | + "3. The last item added is the first one removed (Last In, First Out → LIFO)\n", |
| 410 | + "\n", |
| 411 | + "This can be implemented in python using lists\n", |
| 412 | + "\n", |
| 413 | + "Now depth first seach using stacks:\n", |
| 414 | + "\n", |
| 415 | + "\n", |
| 416 | + "1. Start with the root and put it in the stack.\n", |
| 417 | + "2. Take a node from the stack, check if it’s a leaf (has no children).\n", |
| 418 | + " - If it’s a leaf, save its path.\n", |
| 419 | + " - If not, add its children to the stack (right child first, then left).\n", |
| 420 | + "3. Repeat until we’ve visited all nodes.\n", |
| 421 | + "4. Since we use a stack, we process the left side first (because stacks work in Last In, First Out order)." |
294 | 422 | ]
|
295 | 423 | },
|
296 | 424 | {
|
|
338 | 466 | ],
|
339 | 467 | "metadata": {
|
340 | 468 | "kernelspec": {
|
341 |
| - "display_name": "Python 3", |
| 469 | + "display_name": "dsi_participant", |
342 | 470 | "language": "python",
|
343 | 471 | "name": "python3"
|
344 | 472 | },
|
|
352 | 480 | "name": "python",
|
353 | 481 | "nbconvert_exporter": "python",
|
354 | 482 | "pygments_lexer": "ipython3",
|
355 |
| - "version": "3.11.7" |
| 483 | + "version": "3.9.18" |
356 | 484 | }
|
357 | 485 | },
|
358 | 486 | "nbformat": 4,
|
|
0 commit comments