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
24 changes: 24 additions & 0 deletions src/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

void main() {
MyHashSet myHashSet = new MyHashSet();

myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]

System.out.println(myHashSet.contains(1)); // true
System.out.println(myHashSet.contains(3)); // false

myHashSet.add(2); // set = [1, 2]
System.out.println(myHashSet.contains(2)); // true

myHashSet.remove(2); // set = [1]
System.out.println(myHashSet.contains(2));// false
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(-0);
minStack.push(-3);
System.out.println(minStack.getMin());
minStack.pop();
System.out.println(minStack.top());
System.out.println(minStack.getMin());
}
54 changes: 54 additions & 0 deletions src/MinStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
=I implement the stack using a singly linked list where each node stores (value, minSoFar).
On push, minSoFar is computed as min(val, currentMin) and stored in the new head node.
Top and getMin are always available at the head in O(1) time.
Time Complexity (average):
push: O(1)
pop: O(1)
top: O(1)
getMin: O(1)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : NO
Space Complexity:
O(n)
*/

class MinStack {
private static class Node {
int val;
int minSoFar;
Node next;
Node ( int val, int minSoFar, Node next){
this.val = val;
this.minSoFar = minSoFar;
this.next =next;
}
}

private Node head;
public MinStack(){
head = null;
}
public void push(int val) {
if(head == null){
head = new Node(val,val,null);
}
else{
int newMin = Math.min(val,head.minSoFar);
head = new Node(val,newMin,head);
}

}

public void pop() {
head = head.next;
}

public int top() {
return head.val;
}

public int getMin() {
return head.minSoFar;
}
}
86 changes: 86 additions & 0 deletions src/MyHashSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
I use an array of buckets where each bucket stores a linked list to handle hash collisions using separate chaining.
The key is mapped to a bucket index using a hash function (key % size), and all operations traverse only that bucket.
This gives average O(1) time for add, remove, and contains, with O(n) worst case if many keys collide.
Time Complexity (average):
add: O(1)
remove: O(1)
contains: O(1)
Worst case (many collisions in one bucket):
O(n)

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

class MyHashSet {

private static class Node {
int key;
Node next;
Node(int key) { this.key = key; }
}

private static final int SIZE = 10000; // number of buckets
private Node[] buckets;

public MyHashSet() {
buckets = new Node[SIZE];
}

private int hash(int key) {
return key % SIZE;
}

public void add(int key) {
int idx = hash(key);

// If bucket empty, insert directly
if (buckets[idx] == null) {
buckets[idx] = new Node(key);
return;
}

// Traverse chain to avoid duplicates
Node curr = buckets[idx];
while (true) {
if (curr.key == key) return; // already exists, do nothing
if (curr.next == null) break;
curr = curr.next;
}

// Not found -> append
curr.next = new Node(key);
}

public boolean contains(int key) {
int idx = hash(key);
Node curr = buckets[idx];

while (curr != null) {
if (curr.key == key) return true;
curr = curr.next;
}
return false;
}

public void remove(int key) {
int idx = hash(key);
Node curr = buckets[idx];
Node prev = null;

while (curr != null) {
if (curr.key == key) {
// remove head
if (prev == null) buckets[idx] = curr.next;
else prev.next = curr.next;
return;
}
prev = curr;
curr = curr.next;
}
// not found -> do nothing
}
}