diff --git a/src/main/java/com/company/stack/MinStackImplementation.java b/src/main/java/com/company/stack/MinStackImplementation.java new file mode 100644 index 0000000..208f1d6 --- /dev/null +++ b/src/main/java/com/company/stack/MinStackImplementation.java @@ -0,0 +1,41 @@ +package com.company.stack; + +import java.util.Stack; + +interface MinStack { + public void push(int number); + + public int pop(); + + public int getMin(); +} + +/** + * All the operations of MinStack should be constant value time complexity. O(1) + */ +public class MinStackImplementation implements MinStack { + private final Stack valueStack = new Stack<>(); + private final Stack minStack = new Stack<>(); + + @Override + public void push(int number) { + valueStack.push(number); + if (minStack.empty() || minStack.peek() > number) { + minStack.push(number); + } + } + + @Override + public int pop() { + int topValue = valueStack.pop(); + if (minStack.peek().equals(topValue)) { + minStack.pop(); + } + return topValue; + } + + @Override + public int getMin() { + return minStack.peek(); + } +} \ No newline at end of file diff --git a/src/test/java/com/company/stack/MinStackImplementationTest.java b/src/test/java/com/company/stack/MinStackImplementationTest.java new file mode 100644 index 0000000..18568a5 --- /dev/null +++ b/src/test/java/com/company/stack/MinStackImplementationTest.java @@ -0,0 +1,113 @@ +package com.company.stack; + +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class MinStackImplementationTest { + + @Test + public void getMin_whenMinStackContainsOneNumber_thenReturningTheValue() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int theOnlyOneNumber = 1; + minStackImplementation.push(theOnlyOneNumber); + + // When + int min = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(min).isEqualTo(theOnlyOneNumber); + } + + @Test + public void getMin_whenLastInValueIsNotTheMinValue_andWhenTheLastInValueIsPushed_thenTheMinValuesIsEqualToTheValueBeforePushing() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int firstInValue = 1; + minStackImplementation.push(firstInValue); + int minValueBeforePush = minStackImplementation.getMin(); + + // When + int lastInValueButNeverBeingMin = 10; + minStackImplementation.push(lastInValueButNeverBeingMin); + int min = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(min).isEqualTo(firstInValue); + } + + @Test + public void getMin_whenLastInValueIsTheMinValue_andWhenTheLastInValueIsPushed_thenTheMinValuesShouldBeLastInValue() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int firstInValue = 10; + minStackImplementation.push(firstInValue); + + // When + int lastInValueBeingMinValue = 1; + minStackImplementation.push(lastInValueBeingMinValue); + int min = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(min).isEqualTo(lastInValueBeingMinValue); + } + + @Test + public void getMin_whenTheTopValueIsMinValue_andWhenTheStackPopsTheValue_thenTheMinValuesShouldBeThePreviousMinValue() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int firstInValue = 10; + minStackImplementation.push(firstInValue); + int prevMinValue = minStackImplementation.getMin(); + + int lastInValueBeingMinValue = 1; + minStackImplementation.push(lastInValueBeingMinValue); + + // When + minStackImplementation.pop(); + int minValueAfterPopping = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(minValueAfterPopping).isEqualTo(prevMinValue); + } + + @Test + public void getMin_whenTheTopValueIsNotMinValue_andWhenTheStackPopsTheValue_thenTheMinValuesShouldNotChange() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int firstInValue = 1; + minStackImplementation.push(firstInValue); + + int lastInValueBeingMinValue = 10; + minStackImplementation.push(lastInValueBeingMinValue); + + // When + int minValueBeforePopping = minStackImplementation.getMin(); + minStackImplementation.pop(); + int minValueAfterPopping = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(minValueAfterPopping).isEqualTo(minValueBeforePopping); + } + + @Test + public void getMin_whenTheTopValueIsMinValue_andWhenTheStackPopsTheValue_thenTheMinValueShouldChangeToPreviousMinValue() { + // Given + MinStack minStackImplementation = new MinStackImplementation(); + int firstInValue = 10; + minStackImplementation.push(firstInValue); + + int lastInValueBeingMinValue = 1; + minStackImplementation.push(lastInValueBeingMinValue); + + // When + minStackImplementation.pop(); + int minValueAfterPopping = minStackImplementation.getMin(); + + // Then + Assertions.assertThat(minValueAfterPopping).isEqualTo(firstInValue); + } +} \ No newline at end of file