From bfcf8c70875eef3447fcbc02cceef7842c538483 Mon Sep 17 00:00:00 2001 From: shaurya22c Date: Tue, 28 Jul 2026 21:36:36 -0400 Subject: [PATCH] Completed Design-1 problems --- design_hashset.py | 118 ++++++++++++++++++++++++++++++++++++++++++++++ min_stack.py | 54 +++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 design_hashset.py create mode 100644 min_stack.py diff --git a/design_hashset.py b/design_hashset.py new file mode 100644 index 00000000..c39075d5 --- /dev/null +++ b/design_hashset.py @@ -0,0 +1,118 @@ +""" +Approach: + +we create a list +list index = key +for each index we store/chain elements using linkedlist using a hash function (modulo) + +index values (as linkedlist nodes) +[0] -> [0,10,20,30...] +[1] -> [1,11,21,31...] +[2] -> [2,12,22,32...] +[3] -> [3,13,23,33...] +. +. +[9] -> [9,99,999,9999] + + +Time Complexity: +add, contains, remove: O(1) since we access using key + +Space Complexity: +O(n) since we created hashset using array +""" + + +# we use LinkedList to handle collisions using chaining +class ListNode: + def __init__(self, data, next_node=None): + self.data = data + self.next = next_node + +class MyHashSet: + def __init__(self): + + # create a list + self.set = [] + + # create list of size 10**4 and add a dummy ListNode with data 0 + for _ in range(10**4): + self.set.append(ListNode(0)) + + + def add(self, key: int) -> None: + # to add element, first find the index where we will add + index = self.hash_function(key) + + # convert key to linkedlist to store in that index + new_node = ListNode(key) + + # find the first node at that index + current_node = self.set[index] + + # traverse at the end of linkedlist + while current_node.next: + # if element already exists in that bucket + # we used current_node.next.data instead of current_node.data because our first node is a dummy node with value 0 + if current_node.next.data == key: + return + + current_node = current_node.next + + # now we are at the end of linkedlist and so add element + current_node.next = new_node + + + def contains(self, key: int) -> bool: + index = self.hash_function(key) + current_node = self.set[index] + + while current_node.next: + if current_node.next.data == key: + return True + + current_node = current_node.next + + return False + + def remove(self, key: int) -> None: + index = self.hash_function(key) + current_node = self.set[index] + + while current_node.next: + if current_node.next.data == key: + #just delete that node using next pointer + current_node.next = current_node.next.next + return + current_node = current_node.next + + + # use modulo for hashing + def hash_function(self, key: int) -> int: + index = key%len(self.set) + return index + + def display(self): + print("Display hashset:") + for idx, bucket in enumerate(self.set): + values = [] + current = bucket.next + while current: + values.append(current.data) + current = current.next + if values: + print(f"Bucket {idx}: {values}") + + +def main(): + myHashSet = MyHashSet() + myHashSet.add(10) + myHashSet.add(20) + myHashSet.remove(10) + print(myHashSet.contains(10)) + myHashSet.add(23) + myHashSet.add(23) + myHashSet.display() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/min_stack.py b/min_stack.py new file mode 100644 index 00000000..78924a64 --- /dev/null +++ b/min_stack.py @@ -0,0 +1,54 @@ +""" +Approach: +Implement stack using list. +Create 2 stacks - one regular for push, pop +Second stack will track incoming value and maintain min out of top of stack and incoming value + +Time Complexity: +push, pop, top, getMin: O(1) + +Space Complexity: +O(n) since we store extra list for min + +""" + +class MinStack: + def __init__(self): + self.stack = [] + self.minstack = [] + + def push(self, val: int) -> None: + self.stack.append(val) + + if self.minstack: + min_val = min(val, self.minstack[-1]) + self.minstack.append(min_val) + return + + self.minstack.append(val) + + def pop(self) -> None: + self.stack.pop() + self.minstack.pop() + + def top(self) -> int: + return self.stack[-1] + + def getMin(self) -> int: + return self.minstack[-1] + +def main(): + minStack = MinStack() + minStack.push(-2) + minStack.push(0) + minStack.push(-3) + print("Top value before pop: ", minStack.top()) + print("Min value before pop: ", minStack.getMin()) + + minStack.pop() + print("Top value after pop: ", minStack.top()) + print("Min value after pop: ", minStack.getMin()) + + +if __name__ == "__main__": + main() \ No newline at end of file