From f13fd61e92e3da564bc6e8f7fd71808a9b737398 Mon Sep 17 00:00:00 2001 From: Samiksha Manjunath Date: Fri, 10 Apr 2026 19:19:52 -0700 Subject: [PATCH] Design-1 --- design-hashset.java | 69 +++++++++++++++++++++++++++++++++++++++++++++ min-stack.java | 46 ++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 design-hashset.java create mode 100644 min-stack.java diff --git a/design-hashset.java b/design-hashset.java new file mode 100644 index 00000000..965a6a07 --- /dev/null +++ b/design-hashset.java @@ -0,0 +1,69 @@ +// Time Complexity : O(1) for add, remove, and contains (average case) +// Space Complexity : O(1) effectively (fixed bucket size, not dependent on number of elements inserted) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : Handling edge case for key = 10^6 required allocating extra space for primaryIndex = 0 bucket. + + +// Approach: +// Use a 2D boolean array to simulate a hash set with double hashing. +// First hash (mod) decides the bucket, second hash (division) decides the position inside the bucket. +// Lazy initialization is used to save space, and a special case is handled for index 0 to accommodate max key value. + +class MyHashSet { + int primaryBuckets; + int secondaryBuckets; + boolean[][] storage; + + public MyHashSet() { + this.primaryBuckets = 1000; + this.secondaryBuckets = 1000; + this.storage = new boolean[primaryBuckets][]; + } + + // Primary hash: distributes keys across 1000 buckets + private int getPrimaryHashKey(int key) { + return key % primaryBuckets; + } + + // Secondary hash: position inside each bucket + private int getSecondaryHashKey(int key) { + return key / secondaryBuckets; + } + + public void add(int key) { + int primaryIndex = getPrimaryHashKey(key); + + // Lazy initialization of bucket to save space + if (storage[primaryIndex] == null) { + // Special case for key = 10^6 (falls into bucket 0) + if (primaryIndex == 0) { + storage[primaryIndex] = new boolean[secondaryBuckets + 1]; + } else { + storage[primaryIndex] = new boolean[secondaryBuckets]; + } + } + + int secondaryIndex = getSecondaryHashKey(key); + storage[primaryIndex][secondaryIndex] = true; + } + + public void remove(int key) { + int primaryIndex = getPrimaryHashKey(key); + + // If bucket not initialized, key doesn't exist + if (storage[primaryIndex] == null) return; + + int secondaryIndex = getSecondaryHashKey(key); + storage[primaryIndex][secondaryIndex] = false; + } + + public boolean contains(int key) { + int primaryIndex = getPrimaryHashKey(key); + + // If bucket not initialized, key doesn't exist + if (storage[primaryIndex] == null) return false; + + int secondaryIndex = getSecondaryHashKey(key); + return storage[primaryIndex][secondaryIndex]; + } +} \ No newline at end of file diff --git a/min-stack.java b/min-stack.java new file mode 100644 index 00000000..2c943bc6 --- /dev/null +++ b/min-stack.java @@ -0,0 +1,46 @@ +// Time Complexity : O(1) for push, pop, top, and getMin +// Space Complexity : O(n) due to stack storage (extra space used to store previous minimums) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : No. + + +// Approach: +// Use a single stack but store previous minimum values whenever the current minimum changes or remains same. +// When pushing a new minimum, first push the old minimum, then update min and push the new value. +// During pop, if the popped value is equal to current min, pop again to restore the previous minimum. + +class MinStack { + private Stack stack; + private int min; + + public MinStack() { + this.stack = new Stack<>(); + this.min = Integer.MAX_VALUE; + } + + public void push(int val) { + // If new value is less than or equal to current min, + // store the old min before updating + if (val <= min) { + stack.push(min); + min = val; + } + stack.push(val); + } + + public void pop() { + // If popped value is the current minimum, + // restore the previous minimum from stack + if (min == stack.pop()) { + min = stack.pop(); + } + } + + public int top() { + return stack.peek(); + } + + public int getMin() { + return min; + } +} \ No newline at end of file