diff --git a/02_activities/assignments/assignment_2.ipynb b/02_activities/assignments/assignment_2.ipynb index 26bb3864..a122ec62 100644 --- a/02_activities/assignments/assignment_2.ipynb +++ b/02_activities/assignments/assignment_2.ipynb @@ -27,9 +27,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 68, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], "source": [ "import hashlib\n", "\n", @@ -37,51 +45,74 @@ " hash_object = hashlib.sha256(input_string.encode())\n", " hash_int = int(hash_object.hexdigest(), 16)\n", " return (hash_int % 3) + 1\n", - "input_string = \"your_first_name_here\"\n", + "input_string = \"morolake\"\n", "result = hash_to_range(input_string)\n", "print(result)\n" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "
\n", - " Question 1\n", - "\n", - " # Question One: Check Duplicates in Tree\n", - "\n", - " Given the `root` of a binary tree, check whether it is contains a duplicate value. If a duplicate exists, return the duplicate value. If there are multiple duplicates, return the one with the closest distance to the root. If no duplicate exists, return -1.\n", - "\n", - " ## Examples\n", - "\n", - " ### Example 1\n", - "\n", - " ![](./images/q1_ex1.png)\n", - "\n", - " Input: `root = [1, 2, 2, 3, 5, 6, 7]` *What traversal method is this?*\n", - "\n", - " Output: 2\n", - "\n", - " ### Example 2\n", - "\n", - " ![](./images/q1_ex2.png)\n", + "# Definition for a binary tree node.\n", + "# class TreeNode(object):\n", + "# def __init__(self, val = 0, left = None, right = None):\n", + "# self.val = val\n", + "# self.left = left\n", + "# self.right = right\n", + "def is_duplicate(root: TreeNode) -> int:\n", + "# TODO" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Definition for a binary tree node. Class TreeNode create binary tree node with value, left and right child\n", + "class TreeNode:\n", + " def __init__(self, val = 0, left = None, right = None): # is there every node\n", + " self.val = val # store the actule number of the data\n", + " self.left = left # left child\n", + " self.right = right # right child\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", "\n", - " Input: `root = [1, 10, 2, 3, 10, 12, 12]`\n", + "# Duplicate check using\n", + "def is_duplicate(root: TreeNode) -> int:\n", + " if root is None:\n", + " return - 1\n", "\n", - " Output: 10\n", + " seen = set() # Set (Hash table) for 0(1) search stored visited value\n", + " queue = deque([root]) # Queue Breadth first search (BFS), store nodes to visit next\n", "\n", - " ### Example 3\n", + " while queue:\n", + " current_node = queue.popleft() # run O(n) time , one node at a time\n", "\n", - " ![](./images/q1_ex3.png)\n", + " if current_node_val in seen: # check if the duplicate value exists in our Hash table\n", + " return current_node.val # closest duplicate found\n", + " \n", + " seen.add(current_node.val) # store the value\n", "\n", - " Input: `root = [10, 9, 8, 7]`\n", + " if current_node.left: # add children to the queue \n", + " queue.append(current_node.left) \n", "\n", - " Output: -1\n", + " if current_node.right:\n", + " queue.append(current_node.right) # Record in Hash Table\n", "\n", - "
\n", + " return -1 \n", "\n", - "#### Starter Code for Question 1" + " \n" ] }, { @@ -90,14 +121,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Definition for a binary tree node.\n", - "# class TreeNode(object):\n", - "# def __init__(self, val = 0, left = None, right = None):\n", - "# self.val = val\n", - "# self.left = left\n", - "# self.right = right\n", - "def is_duplicate(root: TreeNode) -> int:\n", - " # TODO" + "#Duplicate in the list\n", + "\n", + "def find_duplicate(lst):\n", + " seen = set() #an empty set called seen\n", + " for num in lst:\n", + " if num in seen:\n", + " return num\n", + " seen.add(num)\n", + " return -1\n", + " \n", + " def Duplicate(lst):\n", + " print(f\"example: {lst} / output: {find_duplicate(lst)}\")" ] }, { @@ -150,6 +185,40 @@ " # TODO" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List\n", + "\n", + "def bt_path(root: TreeNode) -> List[List[int]]:\n", + "\n", + " if not root:\n", + " return []\n", + " result = []\n", + "\n", + " def dfs(node, path):\n", + " path.append(node.val)\n", + "\n", + " # leaf node\n", + "\n", + " if not node.left and not node.right:\n", + " result.append(path.copy())\n", + "\n", + " if node.left:\n", + " dfs(node.left, path)\n", + "\n", + " if node.right:\n", + " dfs(node.right, path)\n", + "\n", + " path.pop() # backtrack\n", + "\n", + " dfs(root, [])\n", + " return result" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -192,10 +261,55 @@ "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1]\n" + ] + } + ], "source": [ + "List = [0,2]\n", + "\n", "def missing_num(nums: List) -> int:\n", - " # TODO" + "\n", + " n = len(nums) \n", + " present = set(nums)\n", + "\n", + " missing = [i for i in range(1, n + 1) if i not in present]\n", + " \n", + " return missing if missing else -1\n", + " \n", + "print (missing_num(List))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[4, 6, 9]\n" + ] + } + ], + "source": [ + "List = [0, 8, 2, 3, 5, 7, 8, 1, 10]\n", + "def missing_num(nums: List) -> int:\n", + "\n", + " n = len(nums) \n", + " present = set(nums)\n", + "\n", + " missing = [i for i in range(1, n + 1) if i not in present]\n", + " \n", + " return missing if missing else -1\n", + "\n", + "print (missing_num(List))" ] }, { @@ -209,6 +323,40 @@ "You and your partner must share each other's Assignment 1 submission." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "https://github.com/Shaifali-Tailor/algorithms_and_data_structures/pull/2/changes/f1572e44eecb0e786555d50beadac648c1fd49cf#diff-dea8636d645d233bc5ecaa8ad9727f005612756e0f52af66e0a59840600f8513" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "import hashlib\n", + "\n", + "def hash_to_range(input_string: str) -> int:\n", + " hash_object = hashlib.sha256(input_string.encode())\n", + " hash_int = int(hash_object.hexdigest(),16)\n", + " return (hash_int % 3) + 1\n", + "input_string = \"shaifali\"\n", + "result = hash_to_range(input_string)\n", + "print(result)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -227,7 +375,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# given a string containing some specific characters, we need to determine if the input string has a correct bracket sequence or not. The string will only contain the characters '(', ')', '{', '}', '[' and ']'. A correct bracket sequence is defined as follows:" ] }, { @@ -244,7 +392,58 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# input: \"({[]})\"\n", + "# output: True" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# example of my partner's solution\n", + "my_str = \"{}[{()}]\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Example of my partners solution\n", + "my_str = \"{}[{{}}]\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "def is_valid_brackets(s: str) -> bool:\n", + " if len(s) % 2 != 0:\n", + " return False\n", + " stack = []\n", + " pairs = {')': '(', '}': '{', ']': '['}\n", + " for ch in s:\n", + " if ch in pairs:\n", + " if not stack or stack[-1] != pairs[ch]:\n", + " return False\n", + " stack.pop()\n", + " else:\n", + " stack.append(ch)\n", + " return not stack\n", + "print(is_valid_brackets(my_str))" ] }, { @@ -261,7 +460,8 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# The solution my partner provided is correct. It uses a stack to keep track of the opening brackets and a mapping to check for matching pairs. The function iterates through each character in the string, pushing opening brackets onto the stack and popping them when a closing bracket is encountered. If the stack is empty at the end, it means all brackets are correctly matched, and the function returns True. Otherwise, it returns False.\n", + "# Going by that, my partner's solution is correct and efficient for checking if the input string has a correct bracket sequence. The time complexity of this solution is O(n), where n is the length of the input string, because we need to iterate through each character once. The space complexity is O(n) in the worst case, when all characters are opening brackets and are stored in the stack." ] }, { @@ -278,7 +478,8 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# The solution's time complexity is O(n) because we need to iterate through each character in the string once. The space complexity is also O(n) in the worst case, when all characters are opening brackets and are stored in the stack.\n", + "# It returns false when it is not matching and true when it is matching. It also checks if the length of the string is odd, in which case it cannot be a valid sequence, and returns false immediately." ] }, { @@ -295,7 +496,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# The problem's time complexity is O(n) as the loop checks once the string for n elements. The space complexity is O(n) in the worst case when all characters are opening brackets and are stored in the stack." ] }, { @@ -312,7 +513,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "# I think my partner did a good job in solving the problem. The solution is efficient and correctly checks for valid bracket sequences. It handles edge cases, such as odd-length strings, and uses a stack to ensure that brackets are properly matched. Overall, I would say that my partner's solution is well-implemented and effective for the given problem." ] }, { @@ -325,20 +526,20 @@ "Please write a 200 word reflection documenting your process from assignment 1, and your presentation and review experience with your partner at the bottom of the Jupyter Notebook under a new heading \"Reflection.\" Again, export this Notebook as pdf.\n" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Reflection" - ] - }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Your answer here" + "\"Reflection\"\n", + "\n", + "# Documenting my reflection from assignment 1, and my experience with the assignment in general. I found the assignment to be quite engaging and thought-provoking. It challenged me to think critically about the problems presented and to apply my knowledge of algorithms and data structures effectively. I appreciated the opportunity to collaborate with a partner, as it allowed us to share ideas and learn from each other's perspectives.\n", + "# Overall, I found the assignment to be a valuable learning experience that helped me deepen my understanding of the concepts covered in class.\n", + "# It was also a great opportunity to practice problem-solving skills and to see how different approaches can lead to the same solution. The way my partner approached the problem was very insightful and helped me see new ways to think about the problem.\n", + "# Data structures and algorithms are fundamental concepts in computer science, and I am grateful for the opportunity to learn about them in this course. I look forward to applying what I've learned in future assignments and projects.\n", + "# Learning about data structures and algorithms has been an eye-opening experience. It has provided me with a deeper understanding of how to efficiently solve problems and optimize code. I have gained insights into various data structures such as arrays, linked lists, stacks, queues, trees, and graphs, as well as algorithms for sorting, searching, and traversing these structures.\n", + "# I look forward to applying what I've learned in future assignments and projects. " ] }, { @@ -396,7 +597,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "algos-env (3.11.14)", "language": "python", "name": "python3" }, @@ -410,7 +611,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.11.14" } }, "nbformat": 4,