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
85 changes: 85 additions & 0 deletions MinStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Time Complexity :
// push(val) -> O(1)
// pop() -> O(1)
// top() -> O(1)
// getMin() -> O(1)
//
// Space Complexity :
// O(N) where N is the number of elements in the stack
// (We use two stacks: one for values, one for tracking minimums)
//
// Did this code successfully run on Leetcode :
// Yes
//
// Any problem you faced while coding this :
// No major issues. The key idea was to:
// - Keep an extra stack to track the minimum at each level
// - Always push the current minimum along with each value
// - Update the min correctly after pop using the min stack


// Your code here along with comments explaining your approach

import java.util.Stack;

class MinStack {

// Main stack to store all values
private Stack<Integer> mainst;

// Auxiliary stack to store the minimum value at each level
private Stack<Integer> minst;

// Variable to track current minimum
private int min;

public MinStack() {
this.mainst = new Stack<>();
this.minst = new Stack<>();

// Initialize min with maximum possible value
this.min = Integer.MAX_VALUE;

// Push initial min so that peek() is always safe
this.minst.push(this.min);
}

public void push(int val) {
// Update the current minimum
min = Math.min(min, val);

// Push value into main stack
mainst.push(val);

// Push the updated minimum into min stack
minst.push(min);
}

public void pop() {
// Pop from both stacks to keep them in sync
mainst.pop();
minst.pop();

// Update current min to the new top of min stack
min = minst.peek();
}

public int top() {
// Return the top of the main stack
return mainst.peek();
}

public int getMin() {
// Return the current minimum value
return min;
}
}

/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
83 changes: 83 additions & 0 deletions MyHashSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Time Complexity :
// add(key) -> Average: O(1), Worst: O(n) (when many keys land in same bucket)
// remove(key) -> Average: O(1), Worst: O(n)
// contains(key) -> Average: O(1), Worst: O(n)
// (n = number of elements in the bucket due to collisions)
//
// Space Complexity :
// O(N + B) where N = total keys stored, B = number of buckets (1000)
//
// Did this code successfully run on Leetcode :
// Yes
//
// Any problem you faced while coding this :
// No major issues. The main thing to be careful about is:
// - Initializing the LinkedList bucket only when needed (lazy init)
// - Removing by value using Integer.valueOf(key) so it doesn't treat key as an index
// - Handling negative keys safely using Math.floorMod


// Your code here along with comments explaining your approach

import java.util.LinkedList;

class MyHashSet {
// Number of buckets (fixed size). More buckets => fewer collisions on average.
int parentbuckets;

// Array of buckets; each bucket is a LinkedList to handle collisions (separate chaining).
LinkedList<Integer>[] storage;

public MyHashSet() {
// Chosen bucket size (common for this LeetCode problem).
this.parentbuckets = 1000;

// Create an array of LinkedLists (buckets). Buckets are initialized lazily.
this.storage = new LinkedList[parentbuckets];
}

// Primary hash function: maps the key into a valid bucket index [0..parentbuckets-1]
// floorMod ensures negative keys also map correctly.
private int getPrimaryHash(int key) {
return Math.floorMod(key, parentbuckets);
}

public void add(int key) {
int index = getPrimaryHash(key);

// Lazy bucket creation (saves memory for unused buckets)
if (storage[index] == null) {
storage[index] = new LinkedList<>();
}

// Avoid duplicates: only add if it's not already present
if (!storage[index].contains(key)) {
storage[index].add(key);
}
}

public void remove(int key) {
int index = getPrimaryHash(key);

// If bucket exists, remove the key if present
if (storage[index] != null) {
// Integer.valueOf(key) removes the object, not by index
storage[index].remove(Integer.valueOf(key));
}
}

public boolean contains(int key) {
int index = getPrimaryHash(key);

// Key exists if bucket exists and it contains the key
return storage[index] != null && storage[index].contains(key);
}
}

/**
* Your MyHashSet object will be instantiated and called as such:
* MyHashSet obj = new MyHashSet();
* obj.add(key);
* obj.remove(key);
* boolean param_3 = obj.contains(key);
*/