Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions design_hashmap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# https://leetcode.com/problems/design-hashmap/


# 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:
def __init__(self):
# initialising the bucket and storage
self.bucket = 1000
self.storage = [None] * self.bucket

class Nodes:
# initialising the attribute of Nodes class
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None

# method to find a bucket in a map to store the key and value
def get_hash(self, key) -> int:
return key % self.bucket

# 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
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
return prev

# method to insert the key and value pair
def put(self, key: int, value: int) -> None:
# find the bucket using the hash method
index = self.get_hash(key)
# 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 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)
# newly provided key value is added next to the node
self.storage[index].next = self.Nodes(key, value)
return
# 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
if prev.next is None:
prev.next = self.Nodes(key, value)
# 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:
index = self.get_hash(key)
# 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 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:
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:
index= self.get_hash(key)
# if bucket is empty
if self.storage[index] is None:
return -1
# 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(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


# 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)
64 changes: 64 additions & 0 deletions queue_using_stacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# https://leetcode.com/problems/implement-queue-using-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:

def __init__(self):
# 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:
# appending an element into the stack
self.in_stack.append(x)

def pop(self) -> int:
# 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:
# 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 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("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)