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
80 changes: 80 additions & 0 deletions MyHashMap_DoubleHashing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Using double hashing

// Time Complexity : O(1)
// Space Complexity : O(1)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No

// Your code here along with comments explaining your approach
// I am using double hashing to handle collisions.
// The hash function is designed to distribute keys evenly across the buckets, reducing the likelihood of collisions.
// When a collision occurs, the second hash function is used to determine the bucket item index, further reducing the
// chance of collisions within the same bucket.
// Also, I am using wrapper class Integer instead of primitive int to handle null values, which is necessary for collision resolution.
// And returing the -1 if key is not found in get method. As int would have default value of 0.


class MyHashMap {

Integer [][] storage;
int buckets;
int bucketItems;

public MyHashMap() {
this.buckets = 1000;
this.bucketItems = 1000;
this.storage = new Integer[buckets][];
}

private int hash1(int key){
return key % buckets;
}
private int hash2(int key){
return key / buckets;
}

// Time Complexity : O(1)
// Space Complexity : O(1)
public void put(int key, int value) {
int bucket = hash1(key);
int bucketItem = hash2(key);

if(storage[bucket] == null){
if(bucket == 0){
storage[bucket] = new Integer[bucketItems + 1];
}else{
storage[bucket] = new Integer[bucketItems];
}

}
storage[bucket][bucketItem] = value;
}

// Time Complexity : O(1)
// Space Complexity : O(1)
public int get(int key) {
int bucket = hash1(key);
int bucketItem = hash2(key);

if(storage[bucket] == null || storage[bucket][bucketItem] == null) return -1;
return storage[bucket][bucketItem];
}

// Time Complexity : O(1)
// Space Complexity : O(1)
public void remove(int key) {
int bucket = hash1(key);
int bucketItem = hash2(key);

if(storage[bucket] == null || storage[bucket][bucketItem] == null) return;
storage[bucket][bucketItem] = null;
}
}

/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
102 changes: 102 additions & 0 deletions MyHashMap_chaining.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Time Complexity : O(1)
// Space Complexity : O(1)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No


// Your code here along with comments explaining your approach
// I am using the chaining approach to implement the hashmap. The basic idea is to use an array of linked lists to store key-value pairs.
// The hash function is used to determine the index in the array where the key-value pair should be stored.
// When a collision occurs, the key-value pair is added to the linked list at that index.
// The search operation involves traversing the linked list at the index to find the key-value pair.
// The put operation involves adding a new key-value pair to the linked list at the index, or updating the value if the key already exists.
// The get operation involves searching the linked list at the index for the key and returning the corresponding value.
// The remove operation involves searching the linked list at the index for the key and removing the key-value pair if found.

class MyHashMap {
private class Node{
int key, value;
Node next;
Node(int key, int value){
this.key = key;
this.value = value;
}
}
private Node [] storage;
private int buckets;
public MyHashMap() {
this.buckets = 10000;
this.storage = new Node[buckets];
}

// Time Complexity : O(1)
// Space Complexity : O(1)
private int myHashFunction (int key){
return key % buckets;
}

// Time Complexity : amortized O(1)
// Space Complexity : O(1)
private Node search(Node head , int key){

Node previousNode = head;
Node currentNode = previousNode.next;

while(currentNode != null && currentNode.key != key){
previousNode = currentNode;
currentNode = currentNode.next;
}
return previousNode;

}

// Time Complexity : amortized O(1)
// Space Complexity : O(1)

public void put(int key, int value) {
int index = myHashFunction(key);
if(storage[index] == null){
storage[index] = new Node(-1,-1);
}
Node prev = search(storage[index], key);
if(prev.next == null){
prev.next = new Node(key, value);
}else{
prev.next.value = value;
}
}

// Time Complexity : amortized O(1)
// Space Complexity : O(1)

public int get(int key) {
int index = myHashFunction(key);
if(storage[index] == null) return -1;

Node prev = search(storage[index], key);

if(prev.next == null || prev.next.key != key) return -1;
return prev.next.value;

}

// Time Complexity : amortized O(1)
// Space Complexity : O(1)

public void remove(int key) {
int index = myHashFunction(key);
if(storage[index] == null) return;
Node prev = search(storage[index], key);
if(prev.next == null) return;
prev.next = prev.next.next;

}
}

/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
65 changes: 65 additions & 0 deletions QueueUsingStacks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No

// Your code here along with comments explaining your approach
// The MyQueue class implements a queue using two stacks. The inStack is used for enqueue operations,
// while the outStack is used for dequeue and peek operations. When the outStack is empty,
// elements are transferred from inStack to outStack to maintain the queue order.

class MyQueue {
Stack<Integer> inStack;
Stack<Integer> outStack;

public MyQueue() {
this.inStack = new Stack<>();
this.outStack = new Stack<>();
}

/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
public void push(int x) {
inStack.push(x);
}

/**
* Time Complexity: Amortized O(1), Worst case O(n)
* Space Complexity: O(1)
*/
public int pop() {
peek();
return outStack.pop();
}

/**
* Time Complexity: Amortized O(1), Worst case O(n)
* Space Complexity: O(1)
*/
public int peek() {
if(outStack.isEmpty()){
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
}
return outStack.peek();
}

/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
}

/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/