Problem
Given a string s
containing just the characters '('
, ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Every close bracket has a corresponding open bracket of the same type.
Examples
Example 1:
Input:
s = "()"
Output:
true
Example 2:
Input:
s = "()[]{}"
Output:
true
Example 3:
Input:
s = "(]"
Output:
false
More Examples
Follow up
- Only One Type of Parenthesis, Say ()
Solution
A typical problem which can be solved by using a stack data structure.
Version1 - When only 1 parenthesis type is present
Method 1 - Using Stack
Why Stack?
Since the last bracket that is opened must also be the first one to be closed, it makes sense to use a data structure that uses the Last In, First Out (LIFO) principle. Therefore, a stack is a good choice here.
Code
Here is the solution:
public static boolean isValid(String str) {
Map<Character, Character> parenthes = new HashMap<>() {{
put('(', ')');
put('{', '}');
put('[', ']');
}};
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (parenthese.containsKey(c)) {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
char cKey = stack.pop();
char cVal = parenthese.get(cKey);
if (cVal != c) {
return false;
}
}
}
return stack.isEmpty();
}
This is O(n) time and O(n) space solution. Can we do better with space?
We can use counter to reduce space. See method 2 with only 1 type of parenthesis.
Dry Run
Lets see algo in action.
Example 1
Consider the following expression {([])}
Example 2
Example 3
Example 4
Method 2 - Using Counter When Only 1 Type of Parenthesis Present
Boolean: IsProperlyNested(String: expression)
Integer: counter = 0
For Each ch In expression
If (ch == '(') Then counter = counter + 1
Else If (ch == ')') Then
counter = counter - 1
If (counter < 0) Then Return False
End If
Next ch
If (counter == 0) Then Return True
Else Return False
IsProperlyNested