Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@
* [InfixToPrefix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java)
* [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
* [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
* [MinStackUsingSingleStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MinStackUsingSingleStack.java)
* [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
* [PostfixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java)
Expand Down Expand Up @@ -1164,6 +1165,7 @@
* [InfixToPostfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java)
* [InfixToPrefixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java)
* [LargestRectangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java)
* [MinStackUsingSingleStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/MinStackUsingSingleStackTest.java)
* [NextGreaterElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java)
* [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
* [PostfixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.thealgorithms.stacks;

import java.util.EmptyStackException;
import java.util.Stack;

/**
* Min-Stack implementation using a single stack.
*
* This stack supports push, pop, and retrieving the minimum element
* in constant time (O(1)) using a modified approach where the stack
* stores both the element and the minimum value so far.
*
* @author Hardvan
*/
public class MinStackUsingSingleStack {
private final Stack<long[]> stack = new Stack<>();

/**
* Pushes a new value onto the stack.
* Each entry stores both the value and the minimum value so far.
*
* @param value The value to be pushed onto the stack.
*/
public void push(int value) {
if (stack.isEmpty()) {
stack.push(new long[] {value, value});
} else {
long minSoFar = Math.min(value, stack.peek()[1]);
stack.push(new long[] {value, minSoFar});
}
}

/**
* Removes the top element from the stack.
*/
public void pop() {
if (!stack.isEmpty()) {
stack.pop();
}
}

/**
* Retrieves the top element from the stack.
*
* @return The top element of the stack.
*/
public int top() {
if (!stack.isEmpty()) {
return (int) stack.peek()[0];
}
throw new EmptyStackException();
}

/**
* Retrieves the minimum element in the stack.
*
* @return The minimum element so far.
*/
public int getMin() {
if (!stack.isEmpty()) {
return (int) stack.peek()[1];
}
throw new EmptyStackException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.thealgorithms.stacks;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.EmptyStackException;
import org.junit.jupiter.api.Test;

public class MinStackUsingSingleStackTest {

@Test
public void testBasicOperations() {
MinStackUsingSingleStack minStack = new MinStackUsingSingleStack();

minStack.push(3);
minStack.push(5);
assertEquals(3, minStack.getMin(), "Minimum should be 3");

minStack.push(2);
minStack.push(1);
assertEquals(1, minStack.getMin(), "Minimum should be 1");

minStack.pop();
assertEquals(2, minStack.getMin(), "Minimum should be 2");

minStack.pop();
assertEquals(3, minStack.getMin(), "Minimum should be 3");
}

@Test
public void testTopElement() {
MinStackUsingSingleStack minStack = new MinStackUsingSingleStack();

minStack.push(8);
minStack.push(10);
assertEquals(10, minStack.top(), "Top element should be 10");

minStack.pop();
assertEquals(8, minStack.top(), "Top element should be 8");
}

@Test
public void testGetMinAfterPops() {
MinStackUsingSingleStack minStack = new MinStackUsingSingleStack();

minStack.push(5);
minStack.push(3);
minStack.push(7);

assertEquals(3, minStack.getMin(), "Minimum should be 3");

minStack.pop(); // Popping 7
assertEquals(3, minStack.getMin(), "Minimum should still be 3");

minStack.pop(); // Popping 3
assertEquals(5, minStack.getMin(), "Minimum should now be 5");
}

@Test
public void testEmptyStack() {
MinStackUsingSingleStack minStack = new MinStackUsingSingleStack();

assertThrows(EmptyStackException.class, minStack::top, "Should throw exception on top()");
assertThrows(EmptyStackException.class, minStack::getMin, "Should throw exception on getMin()");
}
}