diff --git a/MinHeap.py b/MinHeap.py new file mode 100644 index 0000000..37b634b --- /dev/null +++ b/MinHeap.py @@ -0,0 +1,79 @@ + +# Approach: +# A Min-Heap ensures the smallest element is at the root. We represent it as a complete binary tree using an array, +# where for any index `i`, the parent is at `(i - 1) // 2`, the left child at `2 * i + 1`, and the right child at `2 * i + 2`. +# The `insert` operation adds elements and bubbles them up to maintain the heap property, while `extractMin` removes the root and restores order using `heapify`. + +# Time Complexity: +# - `getMin`: O(1) +# - `insert`: O(log n) +# - `extractMin`: O(log n) + +# Space Complexity: O(n) to store the elements in the heap. +# Did this code successfully run on Leetcode: Yes +# Any problem you faced while coding this: No + +class MinHeap: + def __init__(self): + # Initialize an empty list to store heap elements + self.heap = [] + + def getMin(self): + # Return the root element (minimum) of the heap + return self.heap[0] if self.heap else None + + def insert(self, key): + # Add the new key at the end of the heap + self.heap.append(key) + # Move the new key up to maintain the min-heap property + self._bubbleUp(len(self.heap) - 1) + + def _bubbleUp(self, index): + # Move the element at index up until the heap property is satisfied + parent = (index - 1) // 2 + while index > 0 and self.heap[index] < self.heap[parent]: + # Swap the element with its parent + self.heap[index], self.heap[parent] = self.heap[parent], self.heap[index] + index = parent + parent = (index - 1) // 2 + + def extractMin(self): + if not self.heap: + return None + # Replace the root with the last element + root = self.heap[0] + self.heap[0] = self.heap.pop() + # Restore the heap property by heapifying the root + self._heapify(0) + return root + + def _heapify(self, index): + # Heapify the element at index down the tree + smallest = index + left = 2 * index + 1 + right = 2 * index + 2 + + # Check if the left child is smaller + if left < len(self.heap) and self.heap[left] < self.heap[smallest]: + smallest = left + + # Check if the right child is smaller + if right < len(self.heap) and self.heap[right] < self.heap[smallest]: + smallest = right + + # If the smallest is not the current element, swap and continue heapifying + if smallest != index: + self.heap[index], self.heap[smallest] = self.heap[smallest], self.heap[index] + self._heapify(smallest) + +# Example usage +minHeap = MinHeap() +minHeap.insert(3) +minHeap.insert(2) +minHeap.insert(15) +print(minHeap.getMin()) # Output: 2 +print(minHeap.extractMin()) # Output: 2 +print(minHeap.getMin()) # Output: 3 +minHeap.insert(5) +minHeap.insert(4) +print(minHeap.getMin()) # Output: 3 diff --git a/MissingElement.py b/MissingElement.py new file mode 100644 index 0000000..86e0408 --- /dev/null +++ b/MissingElement.py @@ -0,0 +1,28 @@ +# Approach: +# We use a modified binary search since the array is sorted. If the missing number lies between two indices, +# the difference between the value at the middle index and its expected value will help narrow down the search. +# We continue adjusting the search boundaries until we locate the missing number in logarithmic time. + +# Time Complexity: O(log n) because we are using binary search. +# Space Complexity: O(1) since no extra space is used apart from variables. +# Did this code successfully run on Leetcode: Yes +# Any problem you faced while coding this: No + +class Solution: + def missingNumber(self, arr: list[int]) -> int: + left, right = 0, len(arr) - 1 + + # Binary search to find the missing number + while left <= right: + mid = left + (right - left) // 2 # Calculate mid index + + # Check if the middle element is at its expected position + if arr[mid] == mid + 1: + # If it matches, search in the right half + left = mid + 1 + else: + # If it doesn't match, search in the left half + right = mid - 1 + + # When left exceeds right, the missing number is at position 'left' + return left + 1