diff --git a/hashmap_using_linkedlist.py b/hashmap_using_linkedlist.py new file mode 100644 index 00000000..9372293e --- /dev/null +++ b/hashmap_using_linkedlist.py @@ -0,0 +1,76 @@ +"Time Complexity is O(1) on average for put, get, and remove operations. But in worst case (when there are many collisions and elements are stored in the same bucket), the time complexity can go to O(N), where N is the number of elements in the hash map." +"Space Complexity is O(N)" + +#Explanation +"We first inittate a primary data structure lists here with the length of root of maximum value" +"Secondary datastructre chosen here is linkedlist here" +"We will have to always store the prev node while traversing which will help us in all the three functions" + +class ListNode: + def __init__(self, key: int, value: int): + self.key = key + self.value = value + self.next = None # Pointer to the next node +class MyHashMap: + + def __init__(self): + self.buckets = [None] * 10000 + + def getprev(self, key:int, head:ListNode): + prev = ListNode(-1,-1) + current = head + prev.next = current + + while current!=None and current.key!=key: + prev = current + current = current.next + + return prev + + def put(self, key: int, value: int) -> None: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + self.buckets[primaryidx] = ListNode(-1,-1) + + prev = self.getprev(key, self.buckets[primaryidx]) + + if prev.next is None: + prev.next = ListNode(key, value) + else: + prev.next.value = value + + def get(self, key: int) -> int: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + return -1 + + prev = self.getprev(key, self.buckets[primaryidx]) + + if prev.next is None: + return -1 + else: + return prev.next.value + + + def remove(self, key: int) -> None: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + return -1 + + prev = self.getprev(key, self.buckets[primaryidx]) + + if prev.next is None: + return -1 + else: + prev.next = prev.next.next + + + +# 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/hashmap_using_lists.py b/hashmap_using_lists.py new file mode 100644 index 00000000..5e6dcb97 --- /dev/null +++ b/hashmap_using_lists.py @@ -0,0 +1,49 @@ +"Time Complexity is O(1) on average for put, get, and remove operations. But in worst case (when there are many collisions and elements are stored in the same bucket), the time complexity can go to O(N), where N is the number of elements in the hash map." +"Space Complexity is O(N)" + +#Explanation +"We first inittate a primary data structure lists here with the length of root of maximum value" +"Secondary datastructre chosen here is lists again, which will directly help us append, or get a value in average of O(1) times" + +class MyHashMap: + + def __init__(self): + self.buckets = [None] * 1000 + + def put(self, key: int, value: int) -> None: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + self.buckets[primaryidx] = [] + + for i, (k,v) in enumerate(self.buckets[primaryidx]): + if key == k: + self.buckets[primaryidx][i] = (key, value) + return + self.buckets[primaryidx].append((key,value)) + + def get(self, key: int) -> int: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + return -1 + + for k ,v in self.buckets[primaryidx]: + if key == k: + return v + + return -1 + + + def remove(self, key: int) -> None: + primaryidx = key % len(self.buckets) + + if self.buckets[primaryidx] is None: + return -1 + + for i, (k,v) in enumerate(self.buckets[primaryidx]): + if key == k: + self.buckets[primaryidx].remove(self.buckets[primaryidx][i]) + + return -1 + \ No newline at end of file diff --git a/queue_using_stacks.py b/queue_using_stacks.py new file mode 100644 index 00000000..eed9f5de --- /dev/null +++ b/queue_using_stacks.py @@ -0,0 +1,44 @@ +"Time Complexity is O(1) on average since, we will be iterating through first stack and appending the second stack once in a while, and other operations are anyway O(1)" +"Space Complexity is O(N) as we will be using two stacks of the size of N" + +#Explanation + +"We will be using two stacks, one instack and one outstack" +"We keep pushing elements as we get into instack" +"When the operation is pop or peek, we first check if there are no elements in the outstack and then if it is empty, we append all the elements from the instack into the outstack" +"Pop or peek, we always give the latest element added into the out stack and it explains the first element added into the instack" + +class MyQueue: + + def __init__(self): + self.instack = [] + self.outstack = [] + + def push(self, x: int) -> None: + self.instack.append(x) + + def pop(self) -> int: + if len(self.outstack) == 0: + while len(self.instack) != 0: + self.outstack.append(self.instack.pop()) + + return self.outstack.pop() + + def peek(self) -> int: + if len(self.outstack) == 0: + while len(self.instack) != 0: + self.outstack.append(self.instack.pop()) + return self.outstack[-1] + + + def empty(self) -> bool: + return len(self.instack) == 0 and len(self.outstack) == 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