diff --git a/src/main/java/com/thealgorithms/stacks/ValidParentheses.java b/src/main/java/com/thealgorithms/stacks/ValidParentheses.java new file mode 100644 index 000000000000..8ea583cc6475 --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/ValidParentheses.java @@ -0,0 +1,37 @@ +package com.thealgorithms.stacks; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Map; + +public final class ValidParentheses { + + private ValidParentheses() { + throw new AssertionError("Cannot instantiate utility class"); + } + + private static final Map PAIRS = Map.of(')', '(', '}', '{', ']', '['); + + public static boolean isValid(final String s) { + if (s == null) { + throw new NullPointerException("Input cannot be null"); + } + + Deque stack = new ArrayDeque<>(); + for (char ch : s.toCharArray()) { + if (PAIRS.containsValue(ch)) { // opening bracket + stack.push(ch); + } else if (PAIRS.containsKey(ch)) { // closing bracket + // Split logic to satisfy PMD + if (stack.isEmpty()) { + return false; + } + Character top = stack.pop(); + if (top != PAIRS.get(ch)) { + return false; + } + } + } + return stack.isEmpty(); + } +} diff --git a/src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java b/src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java new file mode 100644 index 000000000000..b3689b07d716 --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +/** + * Tests for {@link ValidParentheses}. + */ +public class ValidParenthesesTest { + + @ParameterizedTest + @CsvSource({"'()', true", "'()[]{}', true", "'{[]}', true", "'', true"}) + void testValidParentheses(String input, boolean expected) { + assertEquals(expected, ValidParentheses.isValid(input)); + } + + @ParameterizedTest + @CsvSource({"'(', false", "')', false", "'([)]', false", "'{[}]', false", "'((()', false"}) + void testInvalidParentheses(String input, boolean expected) { + assertEquals(expected, ValidParentheses.isValid(input)); + } + + @ParameterizedTest + @CsvSource({"null"}) + void testNullInput(String input) { + assertThrows(NullPointerException.class, () -> ValidParentheses.isValid(null)); + } +}