From d1393f0f7fb395e8f9eda2614a2afef3f07df2c5 Mon Sep 17 00:00:00 2001 From: Anushri Date: Wed, 12 Nov 2025 15:50:21 -0500 Subject: [PATCH 1/8] implementation using single stack --- queue_using_stacks.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 queue_using_stacks.py diff --git a/queue_using_stacks.py b/queue_using_stacks.py new file mode 100644 index 00000000..621f21f2 --- /dev/null +++ b/queue_using_stacks.py @@ -0,0 +1,39 @@ +# https://leetcode.com/problems/implement-queue-using-stacks/ + +class MyQueue: + + def __init__(self): + # defining empty list + self.queue_list = [] + + # method to append the element to the back of the queue + def push(self, x: int) -> None: + self.queue_list.append(x) + + def pop(self) -> int: + if self.queue_list: + pop_element = self.queue_list[0] + self.queue_list = self.queue_list[1:] + return pop_element + + def peek(self) -> int: + return self.queue_list[0] + + def empty(self) -> bool: + return not self.queue_list + + +# Your MyQueue object will be instantiated and called as such: + +obj = MyQueue() +obj.push(2) +obj.push(3) +obj.push(4) +param_2 = obj.pop() +print(param_2) +param_5 = obj.pop() +print(param_5) +param_3 = obj.peek() +print(param_3) +param_4 = obj.empty() +print(param_4) \ No newline at end of file From f3a6ef417e2839b51c455e74b4350c956b9e8c55 Mon Sep 17 00:00:00 2001 From: Anushri Date: Thu, 13 Nov 2025 19:37:29 -0500 Subject: [PATCH 2/8] implementation using two stack stacks --- queue_using_stacks.py | 68 ++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/queue_using_stacks.py b/queue_using_stacks.py index 621f21f2..c458ad88 100644 --- a/queue_using_stacks.py +++ b/queue_using_stacks.py @@ -1,39 +1,65 @@ # https://leetcode.com/problems/implement-queue-using-stacks/ + + class MyQueue: def __init__(self): - # defining empty list - self.queue_list = [] + # defining empty list becuase we are pushing elements in in_stack and poping and peeking from out_stack + self.in_stack = [] + self.out_stack = [] + # method to append the element to the back of the queue def push(self, x: int) -> None: - self.queue_list.append(x) + # appending an element into the stack + self.in_stack.append(x) def pop(self) -> int: - if self.queue_list: - pop_element = self.queue_list[0] - self.queue_list = self.queue_list[1:] - return pop_element + # if both stacks are empty it returns -1 (empty meethod declared in block 4) + if self.empty(): + return -1 + # else call the peek method which returns first element in the list (peek method declared in block 3) + self.peek() + # once we get the first element pop it + return self.out_stack.pop() + def peek(self) -> int: - return self.queue_list[0] + # proceed if there are elements to look at in the in_stack and out_stack + if not self.empty(): + # this condition searches if the out_stack is empty + if not self.out_stack: + # to get the elements from in_stack to out_stack one by one use while loop + while self.in_stack: + # append the popped element from in_stack into the out_stack + self.out_stack.append(self.in_stack.pop()) + # show the last element from the out_stack (which is the first element of the in_stack) + return self.out_stack[-1] + # if there is nothing in both list return None + return None + def empty(self) -> bool: - return not self.queue_list + # return True if both stacks are empty else return False + return not self.in_stack and not self.out_stack # Your MyQueue object will be instantiated and called as such: -obj = MyQueue() -obj.push(2) -obj.push(3) -obj.push(4) -param_2 = obj.pop() -print(param_2) -param_5 = obj.pop() -print(param_5) -param_3 = obj.peek() -print(param_3) -param_4 = obj.empty() -print(param_4) \ No newline at end of file +# obj = MyQueue() +# obj.push(2) +# obj.push(3) +# obj.push(4) +# param_2 = obj.pop() +# print(param_2) +# param_5 = obj.pop() +# print(param_5) +# param_3 = obj.peek() +# print("peek", param_3) +# param_6 = obj.pop() +# print(param_6) +# param_3 = obj.peek() +# print("peek", param_3) +# param_4 = obj.empty() +# print(param_4) From 5692f7c2f368718275afe34e8ae781aaa329e20b Mon Sep 17 00:00:00 2001 From: Anushri Date: Thu, 13 Nov 2025 19:42:04 -0500 Subject: [PATCH 3/8] Implementation of queue using two stack --- queue_using_stacks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue_using_stacks.py b/queue_using_stacks.py index c458ad88..5b864dd5 100644 --- a/queue_using_stacks.py +++ b/queue_using_stacks.py @@ -1,6 +1,6 @@ # https://leetcode.com/problems/implement-queue-using-stacks/ - +# As in we have to implement FIFO approach we can not use same stack for all operationss. Hence, created two stacks. When we have to apply pop and peek we'll update the second stack and for push we'll update first stack. For checking empty we need to use both stacks class MyQueue: From 595fc7905095f5567a4a9bc14c98c9397f4b612a Mon Sep 17 00:00:00 2001 From: Anushri Date: Fri, 14 Nov 2025 17:23:24 -0500 Subject: [PATCH 4/8] implementation of hashmap with detail logic --- design_hashmap.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 design_hashmap.py diff --git a/design_hashmap.py b/design_hashmap.py new file mode 100644 index 00000000..5a275774 --- /dev/null +++ b/design_hashmap.py @@ -0,0 +1,96 @@ +# https://leetcode.com/problems/design-hashmap/ + +# we are handling dummy -1, -1 for every used bucket. because while remove ooperation link could discrupt so dummy will be constant + +# self.storage is your array of buckets. Each bucket is a linked list. + +# index = self.get_hash(key) tells us which bucket the key belongs to. + +# So self.storage[index] is the head of the linked list for that bucket. + +# creating a class MyHashMap +class MyHashMap: + # need storage to add the key, value pairs. Intialising the storage + def __init__(self): + self.bucket = 1000 + self.storage = [None] * self.bucket + + class Nodes: + # initialing the attribute of Nodes class. This hashmap acts like a linked list so every node has to store a pointer of a next node. Hence this class has three attributes key, value and next. when there is a single node we dont know it's next hence it's default value is None + def __init__(self, key, value): + self.key = key + self.value = value + self.next = None + + # need to find a bucket in a map to store the key and value. it return the bucket + def get_hash(self, key) -> int: + return key % self.bucket + + # method to get the prev pointer in the linked list. we are using linked list so if we have to remove middle node we need to connect previous to the next or to add need to connect previous to the newly added and newly added to the next hence this method is useful + def get_prev(self, head, key): + prev = None + curr = head + # we need to find the prev pointer of the given key so we are looping until we find the key hence we are providing two conditions curr is not None and curr key is not equal to provided key + while curr is not None and curr.key != key: + prev = curr + curr = curr.next + # when we find the matching key exit the loop and make current pointer as previous so that we can perform put and remove function + return prev + + # method to insert the key and value pair + def put(self, key: int, value: int) -> None: + # we are finding the location where the key is stored to do this we call the previously defined method and stored into the variable so that we can use that variable to insert the key + index = self.get_hash(key) + # self.storage[index] is the head of the bucket. if there is nothing in this bucket means no head + if self.storage[index] is None: + # denoting first element is (-1,-1) in hashmap + self.storage[index] = self.Nodes(-1, -1) + # we then attach the key and value which we are providing the next of that dummy node + self.storage[index].next = self.Nodes(key, value) + # We’re saying: “We just created the linked list for this bucket and inserted the first node. No further work is needed, so exit the function + return + # if the bucket is not empty we call the prev method to find the previous pointer of the current key, value. + prev = self.get_prev(self.storage[index], key) + # if the next of the previous is none we can directly add key value pair that is node because there is no node at next + if prev.next is None: + prev.next = self.Nodes(key, value) + # but if there is next node then we need to update the existing value with the new value and key remain unchanged + else: + prev.next.value = value + + # method to return the value of the key + def get(self, key: int) -> int: + # we are finding the location(bucket) where the key is stored to do this we call the previously defined method and stored into the variable so that we can use that variable to insert the key + index = self.get_hash(key) + # self.storage[index] is the head of the bucket. if no keys have been inserted into this bucket yet, it’s empty means no head + if self.storage[index] is None: + return -1 + # call the prev method to find the previous pointer of the current key, value. and at this time self.storage[index] is (-1, -1) beacuse we added this in the put function + prev = self.get_prev(self.storage[index], key) + # if the prev is the last node then there nothing at next so return -1 + if prev.next is None: + return -1 + # If prev.next is not None, it points to the node containing the key. + return prev.next.value + + # method to remove the key and it's correspondent element + def remove(self, key: int) -> None: + # find the bucket + index= self.get_hash(key) + # if there is no head bucket is empty + if self.storage[index] is None: + return -1 + # if there is something in the bucket call the prev method to find the previous pointer of the current key, value. and at this time self.storage[index] is (-1, -1) beacuse we added this in the put functions + prev = self.get_prev(self.storage[index], key) + if prev.next is None: + return -1 + # link the next node of previous with the next to next node + prev.next = prev.next.next + + +# Your MyHashMap object will be instantiated and called as such: +obj = MyHashMap() +obj.put(2,200) +print(obj.put(2,200)) +param_2 = obj.get(2) +obj.remove(2) \ No newline at end of file From 6fc07d89ea27f7293f438c9a30e2a7b9dc239102 Mon Sep 17 00:00:00 2001 From: Anushri Date: Fri, 14 Nov 2025 17:50:02 -0500 Subject: [PATCH 5/8] implementation of hashmap with detailed logic --- design_hashmap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/design_hashmap.py b/design_hashmap.py index 5a275774..98d28cb1 100644 --- a/design_hashmap.py +++ b/design_hashmap.py @@ -1,5 +1,6 @@ # https://leetcode.com/problems/design-hashmap/ +# why we created Nodes class inside the Hashmap- We can do either way. we can create a node class outside # we are handling dummy -1, -1 for every used bucket. because while remove ooperation link could discrupt so dummy will be constant # self.storage is your array of buckets. Each bucket is a linked list. From 76802ab703f628b1208089e1b69f31c43de33097 Mon Sep 17 00:00:00 2001 From: Anushri Date: Fri, 14 Nov 2025 18:23:21 -0500 Subject: [PATCH 6/8] implementation of hashmap --- design_hashmap.py | 48 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/design_hashmap.py b/design_hashmap.py index 98d28cb1..7c54ce93 100644 --- a/design_hashmap.py +++ b/design_hashmap.py @@ -1,72 +1,65 @@ # https://leetcode.com/problems/design-hashmap/ -# why we created Nodes class inside the Hashmap- We can do either way. we can create a node class outside -# we are handling dummy -1, -1 for every used bucket. because while remove ooperation link could discrupt so dummy will be constant - -# self.storage is your array of buckets. Each bucket is a linked list. -# index = self.get_hash(key) tells us which bucket the key belongs to. - -# So self.storage[index] is the head of the linked list for that bucket. +# we are handling dummy -1, -1 for every used bucket. because while remove ooperation link could discrupt so dummy will be constant # creating a class MyHashMap class MyHashMap: - # need storage to add the key, value pairs. Intialising the storage def __init__(self): + # initialising the bucket and storage self.bucket = 1000 self.storage = [None] * self.bucket class Nodes: - # initialing the attribute of Nodes class. This hashmap acts like a linked list so every node has to store a pointer of a next node. Hence this class has three attributes key, value and next. when there is a single node we dont know it's next hence it's default value is None + # initialising the attribute of Nodes class def __init__(self, key, value): self.key = key self.value = value self.next = None - # need to find a bucket in a map to store the key and value. it return the bucket + # method to find a bucket in a map to store the key and value def get_hash(self, key) -> int: return key % self.bucket - # method to get the prev pointer in the linked list. we are using linked list so if we have to remove middle node we need to connect previous to the next or to add need to connect previous to the newly added and newly added to the next hence this method is useful + # we are using linkedlist in the bucket to store the key, value pair. prev pointer is useful to connect the nodes while adding and removing the key. this method finds previous node of the given key def get_prev(self, head, key): prev = None curr = head - # we need to find the prev pointer of the given key so we are looping until we find the key hence we are providing two conditions curr is not None and curr key is not equal to provided key + # we need to find the prev pointer of the given key so we are looping until we find the key while curr is not None and curr.key != key: + # prev is the node before the newly added/removal key prev = curr + # curr is the node for new key curr = curr.next - # when we find the matching key exit the loop and make current pointer as previous so that we can perform put and remove function return prev # method to insert the key and value pair def put(self, key: int, value: int) -> None: - # we are finding the location where the key is stored to do this we call the previously defined method and stored into the variable so that we can use that variable to insert the key + # find the bucket using the hash method index = self.get_hash(key) - # self.storage[index] is the head of the bucket. if there is nothing in this bucket means no head + # if there is nothing in the bucket means we are adding for the first time if self.storage[index] is None: - # denoting first element is (-1,-1) in hashmap + # denoting first element is (-1,-1) in hashmap because while adding or removing the key link could disrupt so dummy acts as a constant at first location self.storage[index] = self.Nodes(-1, -1) - # we then attach the key and value which we are providing the next of that dummy node + # newly provided key value is added next to the node self.storage[index].next = self.Nodes(key, value) - # We’re saying: “We just created the linked list for this bucket and inserted the first node. No further work is needed, so exit the function return - # if the bucket is not empty we call the prev method to find the previous pointer of the current key, value. + # if the bucket is not empty add the time of insertion find the previous pointer of the current key, value pair prev = self.get_prev(self.storage[index], key) - # if the next of the previous is none we can directly add key value pair that is node because there is no node at next + # if the next of the previous is none we can directly add key value pair if prev.next is None: prev.next = self.Nodes(key, value) - # but if there is next node then we need to update the existing value with the new value and key remain unchanged + # but if there is existing node then need to update the existing value with the new value and key remain unchanged else: prev.next.value = value # method to return the value of the key def get(self, key: int) -> int: - # we are finding the location(bucket) where the key is stored to do this we call the previously defined method and stored into the variable so that we can use that variable to insert the key index = self.get_hash(key) - # self.storage[index] is the head of the bucket. if no keys have been inserted into this bucket yet, it’s empty means no head + # if the bucket for that key is empty if self.storage[index] is None: return -1 - # call the prev method to find the previous pointer of the current key, value. and at this time self.storage[index] is (-1, -1) beacuse we added this in the put function + # call the prev method to find the previous pointer of the given key prev = self.get_prev(self.storage[index], key) # if the prev is the last node then there nothing at next so return -1 if prev.next is None: @@ -76,16 +69,15 @@ def get(self, key: int) -> int: # method to remove the key and it's correspondent element def remove(self, key: int) -> None: - # find the bucket index= self.get_hash(key) - # if there is no head bucket is empty + # if bucket is empty if self.storage[index] is None: return -1 - # if there is something in the bucket call the prev method to find the previous pointer of the current key, value. and at this time self.storage[index] is (-1, -1) beacuse we added this in the put functions + # call the prev method to find the previous pointer of the given key prev = self.get_prev(self.storage[index], key) if prev.next is None: return -1 - # link the next node of previous with the next to next node + # link the next node of previous(that is curr which we want to remove) with the next to next node(that is next of the curr) prev.next = prev.next.next From b99a0327fc12168d8f12744fb06d01309f42d270 Mon Sep 17 00:00:00 2001 From: Anushri Date: Fri, 14 Nov 2025 18:38:24 -0500 Subject: [PATCH 7/8] implentation of hashmap --- design_hashmap.py | 2 +- queue_using_stacks.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/design_hashmap.py b/design_hashmap.py index 7c54ce93..1415f7e4 100644 --- a/design_hashmap.py +++ b/design_hashmap.py @@ -1,7 +1,7 @@ # https://leetcode.com/problems/design-hashmap/ -# we are handling dummy -1, -1 for every used bucket. because while remove ooperation link could discrupt so dummy will be constant +# creating a hashmap to store key, value pair. get_hash method is used to find the bucket for the key and then created a get_prev method to find out the previous pointer of the key which about to insert or remove. Then connecting that pointer with new pair while inserting or next pair after the removed pair # creating a class MyHashMap class MyHashMap: diff --git a/queue_using_stacks.py b/queue_using_stacks.py index 5b864dd5..28b495c7 100644 --- a/queue_using_stacks.py +++ b/queue_using_stacks.py @@ -1,6 +1,6 @@ # https://leetcode.com/problems/implement-queue-using-stacks/ -# As in we have to implement FIFO approach we can not use same stack for all operationss. Hence, created two stacks. When we have to apply pop and peek we'll update the second stack and for push we'll update first stack. For checking empty we need to use both stacks +# As we have to implement FIFO approach we can not use same stack for all operationss. Hence, created two stacks. When we have to apply pop and peek we'll update the second stack and for push we'll update first stack. For checking empty we need to use both stacks class MyQueue: From bcecc29c07a63ef48cdda542cf0dd975a8138ddb Mon Sep 17 00:00:00 2001 From: Anushri Date: Fri, 14 Nov 2025 18:41:10 -0500 Subject: [PATCH 8/8] implentation of queue using two stack --- queue_using_stacks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/queue_using_stacks.py b/queue_using_stacks.py index 28b495c7..8af5d487 100644 --- a/queue_using_stacks.py +++ b/queue_using_stacks.py @@ -46,7 +46,6 @@ def empty(self) -> bool: # Your MyQueue object will be instantiated and called as such: - # obj = MyQueue() # obj.push(2) # obj.push(3)