diff --git a/src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java b/src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java new file mode 100644 index 000000000..be9d0099d --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java @@ -0,0 +1,74 @@ +package com.thealgorithms.stacks; + +import java.util.NoSuchElementException; +import java.util.Stack; + +/** + * A class that implements a stack that gives the maximum element in O(1) time. + * The mainStack is used to store the all the elements of the stack + * While the maxStack stores the maximum elements + * When we want to get a maximum element, we call the top of the maximum stack + * + * Problem: https://www.baeldung.com/cs/stack-constant-time + */ +public class GreatestElementConstantTime { + private Stack mainStack; // initialize a mainStack + private Stack maxStack; // initialize a maxStack + + /** + * Constructs two empty stacks + */ + public GreatestElementConstantTime() { + mainStack = new Stack<>(); + maxStack = new Stack<>(); + } + + /** + * Pushes an element onto the top of the stack. + * Checks if the element is the maximum or not + * If so, then pushes to the maximum stack + * @param data The element to be pushed onto the stack. + */ + public void push(int data) { + if (mainStack.isEmpty()) { + mainStack.push(data); + maxStack.push(data); + return; + } + + mainStack.push(data); + if (data > maxStack.peek()) { + maxStack.push(data); + } + } + + /** + * Pops an element from the stack. + * Checks if the element to be popped is the maximum or not + * If so, then pop from the minStack + * + * @throws NoSuchElementException if the stack is empty. + */ + public void pop() { + if (mainStack.isEmpty()) { + throw new NoSuchElementException("Stack is empty"); + } + + int ele = mainStack.pop(); + if (ele == maxStack.peek()) { + maxStack.pop(); + } + } + + /** + * Returns the maximum element present in the stack + * + * @return The element at the top of the maxStack, or null if the stack is empty. + */ + public Integer getMaximumElement() { + if (maxStack.isEmpty()) { + return null; + } + return maxStack.peek(); + } +} diff --git a/src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java b/src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java new file mode 100644 index 000000000..9864ef9b0 --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java @@ -0,0 +1,74 @@ +package com.thealgorithms.stacks; + +import java.util.NoSuchElementException; +import java.util.Stack; + +/** + * A class that implements a stack that gives the minimum element in O(1) time. + * The mainStack is used to store the all the elements of the stack + * While the minStack stores the minimum elements + * When we want to get a minimum element, we call the top of the minimum stack + * + * Problem: https://www.baeldung.com/cs/stack-constant-time + */ +public class SmallestElementConstantTime { + private Stack mainStack; // initialize a mainStack + private Stack minStack; // initialize a minStack + + /** + * Constructs two empty stacks + */ + public SmallestElementConstantTime() { + mainStack = new Stack<>(); + minStack = new Stack<>(); + } + + /** + * Pushes an element onto the top of the stack. + * Checks if the element is the minimum or not + * If so, then pushes to the minimum stack + * @param data The element to be pushed onto the stack. + */ + public void push(int data) { + if (mainStack.isEmpty()) { + mainStack.push(data); + minStack.push(data); + return; + } + + mainStack.push(data); + if (data < minStack.peek()) { + minStack.push(data); + } + } + + /** + * Pops an element from the stack. + * Checks if the element to be popped is the minimum or not + * If so, then pop from the minStack + * + * @throws NoSuchElementException if the stack is empty. + */ + public void pop() { + if (mainStack.isEmpty()) { + throw new NoSuchElementException("Stack is empty"); + } + + int ele = mainStack.pop(); + if (ele == minStack.peek()) { + minStack.pop(); + } + } + + /** + * Returns the minimum element present in the stack + * + * @return The element at the top of the minStack, or null if the stack is empty. + */ + public Integer getMinimumElement() { + if (minStack.isEmpty()) { + return null; + } + return minStack.peek(); + } +} diff --git a/src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java b/src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java new file mode 100644 index 000000000..080592dc6 --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.NoSuchElementException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class GreatestElementConstantTimeTest { + + private GreatestElementConstantTime constantTime; + + @BeforeEach + public void setConstantTime() { + constantTime = new GreatestElementConstantTime(); + } + + @Test + public void testMaxAtFirst() { + constantTime.push(1); + constantTime.push(10); + constantTime.push(20); + constantTime.push(5); + assertEquals(20, constantTime.getMaximumElement()); + } + + @Test + public void testMinTwo() { + constantTime.push(5); + constantTime.push(10); + constantTime.push(20); + constantTime.push(1); + assertEquals(20, constantTime.getMaximumElement()); + constantTime.pop(); + constantTime.pop(); + assertEquals(10, constantTime.getMaximumElement()); + } + + @Test + public void testNullMax() { + constantTime.push(10); + constantTime.push(20); + constantTime.pop(); + constantTime.pop(); + assertNull(constantTime.getMaximumElement()); + } + + @Test + public void testBlankHandle() { + constantTime.push(10); + constantTime.push(1); + constantTime.pop(); + constantTime.pop(); + assertThrows(NoSuchElementException.class, () -> constantTime.pop()); + } + + @Test + public void testPushPopAfterEmpty() { + constantTime.push(10); + constantTime.push(1); + constantTime.pop(); + constantTime.pop(); + constantTime.push(5); + assertEquals(5, constantTime.getMaximumElement()); + constantTime.push(1); + assertEquals(5, constantTime.getMaximumElement()); + } +} diff --git a/src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java b/src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java new file mode 100644 index 000000000..b5eda9e8c --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.NoSuchElementException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SmallestElementConstantTimeTest { + + private SmallestElementConstantTime sect; + + @BeforeEach + public void setSect() { + sect = new SmallestElementConstantTime(); + } + + @Test + public void testMinAtFirst() { + sect.push(1); + sect.push(10); + sect.push(20); + sect.push(5); + assertEquals(1, sect.getMinimumElement()); + } + + @Test + public void testMinTwo() { + sect.push(5); + sect.push(10); + sect.push(20); + sect.push(1); + assertEquals(1, sect.getMinimumElement()); + sect.pop(); + assertEquals(5, sect.getMinimumElement()); + } + + @Test + public void testNullMin() { + sect.push(10); + sect.push(20); + sect.pop(); + sect.pop(); + assertNull(sect.getMinimumElement()); + } + + @Test + public void testBlankHandle() { + sect.push(10); + sect.push(1); + sect.pop(); + sect.pop(); + assertThrows(NoSuchElementException.class, () -> sect.pop()); + } + + @Test + public void testPushPopAfterEmpty() { + sect.push(10); + sect.push(1); + sect.pop(); + sect.pop(); + sect.push(5); + assertEquals(5, sect.getMinimumElement()); + sect.push(1); + assertEquals(1, sect.getMinimumElement()); + } +}