From 09617a0420e9d8cc38d2a15dc664255885fca1c4 Mon Sep 17 00:00:00 2001 From: Sanket Kale Date: Thu, 4 Jun 2026 21:42:54 -0500 Subject: [PATCH] Completed Design 2 --- Problem1.py | 51 +++++++++++++++++++++++++++++++++++ Problem2.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +-- 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 Problem1.py create mode 100644 Problem2.py diff --git a/Problem1.py b/Problem1.py new file mode 100644 index 00000000..c9f9d9b9 --- /dev/null +++ b/Problem1.py @@ -0,0 +1,51 @@ +## Problem 1: (https://leetcode.com/problems/implement-queue-using-stacks/) + +class MyQueue: + + # We will use 2 stacks: + # always push to the inStack + # always pop from the outStack + def __init__(self): + self.inStack = [] + self.outStack = [] + + # always push to the inStack + def push(self, x: int) -> None: + self.inStack.append(x) + + + # Complexity: Best Case: O(1); Worst Case: O(n) when we need to invert the inStack + # As Stack is LIFO and Queue is FIFO, we can't pop from the inStack + # because top of the stack will be the last element that was added and not the first + # and the first element is at the bottom, so we need to reverse the stack + def pop(self) -> int: + # we will use the outStack to reverse the inStack + # simply pop from the inStack and add to the outStack + # now the outStack will have the first element on top + if len(self.outStack) == 0: + while len(self.inStack): + self.outStack.append(self.inStack.pop()) + + # outStack will always have the elements in FIFO order + # so always pop from here + return self.outStack.pop() + + # Complexity: O(1) + def peek(self) -> int: + if len(self.outStack): # always peek from top of outStack + return self.outStack[-1] + else: # but if the outStack is empty, return the 1st element in the inStack + return self.inStack[0] + + # simply check if both the stacks are empty + # Complexity: O(1) + def empty(self) -> bool: + return len(self.outStack) == 0 and len(self.inStack) == 0 + + +# Your MyQueue object will be instantiated and called as such: +# obj = MyQueue() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.peek() +# param_4 = obj.empty() \ No newline at end of file diff --git a/Problem2.py b/Problem2.py new file mode 100644 index 00000000..024825dc --- /dev/null +++ b/Problem2.py @@ -0,0 +1,77 @@ +## Problem 2: Design Hashmap (https://leetcode.com/problems/design-hashmap/) + +class MyHashMap: + class Node: + def __init__(self, key: int = -1, val: int = -1, next_node: 'Node' | None = None): + self.key = key + self.val = val + self.next = next_node + + # We will use chaining, so we want the link list to be small enough + # so our map will be of seze 10^4 + # and link list's will have at max 10^2 nodes + def __init__(self): + self.n = 10000 + self.hashMap = [self.Node() for _ in range(self.n)] # we will init the hashMap with dummy nodes + + + # Complexity: O(1) + def put(self, key: int, value: int) -> None: + index = self.getHashKey(key) + previous = self.findPrevious(index, key) + + # previous.next will only be there when key is found in the linked list + # so we need to update the value + if previous.next: + previous.next.val = value + else: # else insert a new node + previous.next = self.Node(key, value) + + # Complexity: O(1) + def get(self, key: int) -> int: + index = self.getHashKey(key) + previous = self.findPrevious(index, key) + + if previous.next and previous.next.key == key: + return previous.next.val + return -1 + + # Complexity: O(1) + def remove(self, key: int) -> None: + index = self.getHashKey(key) + previous = self.findPrevious(index, key) + + # if key, value is present in the linked list, break the link + if previous.next and previous.next.key == key: + temp = previous.next + previous.next = previous.next.next + temp.next = None + + + def getHashKey(self, key: int) -> int: + return key % self.n + + # this is a helper function + # we need to find the previous in each operation sine we are using a linked list + # we mainly need previous for the remove operation to break the link + # but for adding/updating a node, if we know the previous, we can add to its next + # O(1) since linked list is small enough + def findPrevious(self, index: int, key: int) -> 'Node': + previous = None + current = self.hashMap[index] + + while current: + if current.key == key: + break + + previous = current + current = current.next + + return previous + + +# Your MyHashMap object will be instantiated and called as such: +# obj = MyHashMap() +# obj.put(key,value) +# param_2 = obj.get(key) +# obj.remove(key) \ No newline at end of file diff --git a/README.md b/README.md index ff1cd0e0..504c4a25 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ Explain your approach in **three sentences only** at top of your code ## Problem 1: (https://leetcode.com/problems/implement-queue-using-stacks/) -## Problem 2: -Design Hashmap (https://leetcode.com/problems/design-hashmap/) +## Problem 2: Design Hashmap (https://leetcode.com/problems/design-hashmap/)