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
90 changes: 90 additions & 0 deletions DesignHashMap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'''
Here I implemented my Hashmap using linear chaining for handling collisions, using a hash function.
put():
- with the index returned from hash function we go to the index and check if the index already has a chain initialized.
- if not we add a dummy node before creating the head node(because when the head had to be removed from the storage array,
it will break the connection to rest of the elements)
- if it already has values then we connect the new values to existing node.
get():
we directly fetch the value from the key
remove():
from the find we get the prevois node and delete the prev.next and connect prev.next to prev.next.next
'''

class MyHashMap:

class Node:
def __init__(self, key, val):
self.key = key
self.val = val
self.next = None

def __init__(self):
self.size = 10000
self.storage = [None] * self.size

# hash function for equal distribution
def hashFunc(self, key: int)-> int:
return key % self.size

# function to find the prev node
def find(self, head, key):
prev = None
curr = head
while curr is not None and curr.key != key:
prev = curr
curr = curr.next
return prev

def put(self, key: int, value: int) -> None:
idx = self.hashFunc(key)

# to check if the index has any chain, if not create a dummy pair
if self.storage[idx] is None:
self.storage[idx] = self.Node(-1,-1)

# to find the previous node of the target key
prev = self.find(self.storage[idx], key)

# if the index has values append with new values
if prev.next:
prev.next.val = value
else:
prev.next = self.Node(key, value)

def get(self, key: int) -> int:
idx = self.hashFunc(key)

# if no linked list exists at the index
if self.storage[idx] is None:
return -1
# to find the previous node of the target key
prev = self.find(self.storage[idx], key)

# if exists return the value
if prev.next:
return prev.next.val

# if the key is not found return -1
return -1

def remove(self, key: int) -> None:
idx = self.hashFunc(key)

# to check if it has no elements in that if not return
if self.storage[idx] is None:
return

# to find the previous node of the target key
prev = self.find(self.storage[idx], key)

if prev.next is None:
return

# to link previous node to next node of removed node
prev.next = prev.next.next

'''
Time Complexity: O(1)
Space Complexity: O(1)
'''
42 changes: 42 additions & 0 deletions ImplementQueueUsingStacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'''
For designing a Queue using stack, we initialize 2 stacks
push: we push elements into inStack for every push operation
pop: we pop elements from both the stacks, first we pop all the elemnts one after other from inStack to outStack,
from outStack we only pop the top most value
empty: we return true if only both the stacks are empty
'''

class MyQueue:

# we define 2 stacks
def __init__(self):
self.inStack = []
self.outStack = []

# we add the push values to inStack
def push(self, x: int) -> None:
self.inStack.append(x)

# popping from both the stacks to pop the first elemt
def pop(self) -> int:
if not self.outStack:
while self.inStack:
self.outStack.append(self.inStack.pop())
# self.peek()
return self.outStack.pop()

# first element from the outStack
def peek(self) -> int:
if not self.outStack:
while self.inStack:
self.outStack.append(self.inStack.pop())
return self.outStack[-1]

# to check if both the stacks are empty and return true
def empty(self) -> bool:
return not self.inStack and not self.outStack

'''
Time Complexity: O(1)
Space Complexity: O(1)
'''