Skip to content

Commit 6d8f87b

Browse files
committed
refactor: optimize ValidParentheses methods and add parameterized tests
1 parent fa2ca9d commit 6d8f87b

File tree

2 files changed

+55
-62
lines changed

2 files changed

+55
-62
lines changed
Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,57 @@
11
package com.thealgorithms.strings;
2-
// Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine
3-
// if the input string is valid. An input string is valid if: Open brackets must be closed by
4-
// the same type of brackets. Open brackets must be closed in the correct order. Every close
5-
// bracket has a corresponding open bracket of the same type.
62

3+
import java.util.ArrayDeque;
4+
import java.util.Deque;
5+
import java.util.Map;
6+
7+
/**
8+
* Validates if a given string has valid matching parentheses.
9+
* <p>
10+
* A string is considered valid if:
11+
* <ul>
12+
* <li>Open brackets are closed by the same type of brackets.</li>
13+
* <li>Brackets are closed in the correct order.</li>
14+
* <li>Every closing bracket has a corresponding open bracket of the same type.</li>
15+
* </ul>
16+
*
17+
* Allowed characters: '(', ')', '{', '}', '[', ']'
18+
*/
719
public final class ValidParentheses {
820
private ValidParentheses() {
921
}
22+
23+
private static final Map<Character, Character> BRACKET_PAIRS = Map.of(
24+
')', '(',
25+
'}', '{',
26+
']', '['
27+
);
28+
29+
/**
30+
* Checks if the input string has valid parentheses.
31+
*
32+
* @param s the string containing only bracket characters
33+
* @return true if valid, false otherwise
34+
* @throws IllegalArgumentException if the string contains invalid characters or is null
35+
*/
1036
public static boolean isValid(String s) {
11-
char[] stack = new char[s.length()];
12-
int head = 0;
37+
if (s == null) {
38+
throw new IllegalArgumentException("Input string cannot be null");
39+
}
40+
41+
Deque<Character> stack = new ArrayDeque<>();
42+
1343
for (char c : s.toCharArray()) {
14-
switch (c) {
15-
case '{':
16-
case '[':
17-
case '(':
18-
stack[head++] = c;
19-
break;
20-
case '}':
21-
if (head == 0 || stack[--head] != '{') {
22-
return false;
23-
}
24-
break;
25-
case ')':
26-
if (head == 0 || stack[--head] != '(') {
27-
return false;
28-
}
29-
break;
30-
case ']':
31-
if (head == 0 || stack[--head] != '[') {
44+
if (BRACKET_PAIRS.containsValue(c)) {
45+
stack.push(c); // opening bracket
46+
} else if (BRACKET_PAIRS.containsKey(c)) {
47+
if (stack.isEmpty() || stack.pop() != BRACKET_PAIRS.get(c)) {
3248
return false;
3349
}
34-
break;
35-
default:
36-
throw new IllegalArgumentException("Unexpected character: " + c);
37-
}
38-
}
39-
return head == 0;
40-
}
41-
public static boolean isValidParentheses(String s) {
42-
int i = -1;
43-
char[] stack = new char[s.length()];
44-
String openBrackets = "({[";
45-
String closeBrackets = ")}]";
46-
for (char ch : s.toCharArray()) {
47-
if (openBrackets.indexOf(ch) != -1) {
48-
stack[++i] = ch;
4950
} else {
50-
if (i >= 0 && openBrackets.indexOf(stack[i]) == closeBrackets.indexOf(ch)) {
51-
i--;
52-
} else {
53-
return false;
54-
}
51+
throw new IllegalArgumentException("Unexpected character: " + c);
5552
}
5653
}
57-
return i == -1;
54+
55+
return stack.isEmpty();
5856
}
5957
}
Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
package com.thealgorithms.strings;
22

3-
import static org.junit.jupiter.api.Assertions.assertFalse;
4-
import static org.junit.jupiter.api.Assertions.assertTrue;
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
54

6-
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.Arguments;
7+
import org.junit.jupiter.params.provider.MethodSource;
78

8-
public class ValidParenthesesTest {
9+
import java.util.stream.Stream;
910

10-
@Test
11-
void testOne() {
12-
assertTrue(ValidParentheses.isValid("()"));
13-
assertTrue(ValidParentheses.isValidParentheses("()"));
14-
}
11+
public class ValidParenthesesTest {
1512

16-
@Test
17-
void testTwo() {
18-
assertTrue(ValidParentheses.isValid("()[]{}"));
19-
assertTrue(ValidParentheses.isValidParentheses("()[]{}"));
13+
@ParameterizedTest(name = "Input: \"{0}\" → Expected: {1}")
14+
@MethodSource("parenthesesProvider")
15+
void testIsValid(String input, boolean expected) {
16+
assertEquals(expected, ValidParentheses.isValid(input));
2017
}
2118

22-
@Test
23-
void testThree() {
24-
assertFalse(ValidParentheses.isValid("(]"));
25-
assertFalse(ValidParentheses.isValidParentheses("(]"));
19+
static Stream<Arguments> parenthesesProvider() {
20+
return Stream.of(Arguments.of("()", true), Arguments.of("()[]{}", true), Arguments.of("(]", false), Arguments.of("{[]}", true), Arguments.of("([{}])", true), Arguments.of("([)]", false), Arguments.of("", true), Arguments.of("(", false), Arguments.of(")", false));
2621
}
2722
}

0 commit comments

Comments
 (0)