From c6e4ccedc17b365adc3884284fe15260e3a0179f Mon Sep 17 00:00:00 2001 From: abhayb94 Date: Sat, 2 Sep 2023 14:23:15 -0400 Subject: [PATCH 1/2] Design 1 - Completed --- MinStack.java | 56 ++++++++++++++++++++++++++++++++++++ MyHashSet.java | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 MinStack.java create mode 100644 MyHashSet.java diff --git a/MinStack.java b/MinStack.java new file mode 100644 index 00000000..2afb3323 --- /dev/null +++ b/MinStack.java @@ -0,0 +1,56 @@ +package org.example; + +import java.util.*; + +// 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 +// The basic idea is to use a single stack and initially the min is assumed to be infinity. When a value less the current minimum is identified, +// then push the previous minimum followed by the new value. And when popping, pop the top of the stack and the next element below it if the +// popped value is currently the minimum, then the lastly popped element will be the new minimum + +class MinStack { + Stack st; + + int min; + public MinStack() { + this.st = new Stack<>(); + this.min = Integer.MAX_VALUE; + + } + + public void push(int val) { + if(min>= val){ + st.push(min); + min = val; + } + st.push(val); + } + + public void pop() { + if(st.pop() == min){ + min = st.pop(); + } + } + + public int top() { + return st.peek(); + } + + public int getMin() { + 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(); + */ diff --git a/MyHashSet.java b/MyHashSet.java new file mode 100644 index 00000000..9561c1e2 --- /dev/null +++ b/MyHashSet.java @@ -0,0 +1,77 @@ +package org.example; + +// 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 +// The values are mapped to the array by using double hashing to resolve collisions here(hash1 and hash2). The primary array storage will save +// the address to the secondary array which in turn will save the elements in it post computing the hash value using hash2. The index range for +// both primary and the secondary array are taken based on square root method on the upper bound provided. + + +public class MyHashSet { + + boolean [][] storage; + int buckets; // size of primary array + int bucketItems; // size of second array + + public MyHashSet() { + + this.buckets = 1000; + this.bucketItems = 1000; + this.storage = new boolean [1000][]; + } + + private int hash1 (int key){ + return key % 1000; + } + private int hash2 (int key){ + return key / 1000; + } + + + public void add(int key) { // Time Complexity = O[1] + int bucket = hash1(key); + int bucketItem = hash2(key); + + if(storage[bucket] == null){ // check if bucket is null or not + if(bucket == 0){ + bucketItems++; + } + storage[bucket] = new boolean[bucketItems]; + } + storage[bucket][bucketItem] = true; + } + + public void remove(int key) { // Time Complexity = O[1] + int bucket = hash1(key); + int bucketItem = hash2(key); + + if(storage[bucket] == null){ // check if bucket is null or not + return; + } + storage[bucket][bucketItem] = false; + } + + public boolean contains(int key) { // Time Complexity = O[1] + int bucket = hash1(key); + int bucketItem = hash2(key); + + if(storage[bucket] == null){ // check if bucket is null or not + return false; + } + return storage[bucket][bucketItem]; + + } +} + +/** + * 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); + */ \ No newline at end of file From 5b638ce6a99622024d30c0dfb3c9527e6ae91580 Mon Sep 17 00:00:00 2001 From: abhayb94 Date: Fri, 26 Dec 2025 17:13:58 -0500 Subject: [PATCH 2/2] completed implementation of min stack using single stack and designed the hash set using nested arrays and double hashing --- MinStack.java | 21 ++++++++++---------- MyHashSet.java | 54 +++++++++++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/MinStack.java b/MinStack.java index 2afb3323..7c958356 100644 --- a/MinStack.java +++ b/MinStack.java @@ -13,32 +13,33 @@ // then push the previous minimum followed by the new value. And when popping, pop the top of the stack and the next element below it if the // popped value is currently the minimum, then the lastly popped element will be the new minimum +// Using one stack class MinStack { - Stack st; - + Stack stack; int min; + public MinStack() { - this.st = new Stack<>(); this.min = Integer.MAX_VALUE; - + this.stack = new Stack<>(); } public void push(int val) { if(min>= val){ - st.push(min); + stack.push(min); min = val; } - st.push(val); + stack.push(val); } public void pop() { - if(st.pop() == min){ - min = st.pop(); + if(stack.pop() == min){ + min = stack.pop(); } + } public int top() { - return st.peek(); + return stack.peek(); } public int getMin() { @@ -53,4 +54,4 @@ public int getMin() { * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); - */ + */ \ No newline at end of file diff --git a/MyHashSet.java b/MyHashSet.java index 9561c1e2..89be18c1 100644 --- a/MyHashSet.java +++ b/MyHashSet.java @@ -12,17 +12,15 @@ // both primary and the secondary array are taken based on square root method on the upper bound provided. -public class MyHashSet { - +class MyHashSet { boolean [][] storage; - int buckets; // size of primary array - int bucketItems; // size of second array + int buckets; // size of the primary array + int bucketItems; // size of the secondary array public MyHashSet() { - this.buckets = 1000; this.bucketItems = 1000; - this.storage = new boolean [1000][]; + this.storage = new boolean[1000][]; } private int hash1 (int key){ @@ -31,43 +29,45 @@ private int hash1 (int key){ private int hash2 (int key){ return key / 1000; } - - - public void add(int key) { // Time Complexity = O[1] - int bucket = hash1(key); + public void add(int key) { + // Time Complexity : O(1) + // Space Complexity : O(1) + int bucket = hash1(key); int bucketItem = hash2(key); - if(storage[bucket] == null){ // check if bucket is null or not - if(bucket == 0){ - bucketItems++; + if(storage[bucket] == null){ + if(bucket == 0){ // condition to handle 10^6 + storage[bucket] = new boolean[bucketItems + 1]; + }else{ + storage[bucket] = new boolean[bucketItems]; } - storage[bucket] = new boolean[bucketItems]; + } storage[bucket][bucketItem] = true; } - public void remove(int key) { // Time Complexity = O[1] - int bucket = hash1(key); + public void remove(int key) { + // Time Complexity : O(1) + // Space Complexity : O(1) + int bucket = hash1(key); int bucketItem = hash2(key); - - if(storage[bucket] == null){ // check if bucket is null or not - return; - } + if(storage[bucket] == null) return; storage[bucket][bucketItem] = false; + } - public boolean contains(int key) { // Time Complexity = O[1] - int bucket = hash1(key); + public boolean contains(int key) { + // Time Complexity : O(1) + // Space Complexity : O(1) + int bucket = hash1(key); int bucketItem = hash2(key); - - if(storage[bucket] == null){ // check if bucket is null or not - return false; - } + if(storage[bucket] == null) return false; return storage[bucket][bucketItem]; - } } + + /** * Your MyHashSet object will be instantiated and called as such: * MyHashSet obj = new MyHashSet();