Given a string containing just the characters '(', ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
The brackets must close in the correct order, "()"
and "()[]{}"
are all valid but "(]"
and "([)]"
are not.
This problem itself is pretty straightforward in developing a solution. Each time we try to check a parenthese pair,
we need to get the previous character that was just scanned, indicating a LIFO visit order. So we need to use the
stack data structure as follows.
1. Each time we have a right side parenthese, we check the stack. If the stack is either empty or its top element is
not a matching left side parenthese, return false.
2. If we have a left side parenthese, simply push it to the stack.
3. After all characters have been iterated, check if the stack is empty. If empty, return true, otherwise return false.
1 public class Solution { 2 /** 3 * @param s A string 4 * @return whether the string is a valid parentheses 5 */ 6 public boolean isValidParentheses(String s) { 7 if(s == null){ 8 return false; 9 } 10 if(s.length() == 0){ 11 return true; 12 } 13 if(s.length() % 2 != 0){ 14 return false; 15 } 16 Stack<Character> stack = new Stack<Character>(); 17 int idx = 0; 18 while(idx < s.length()){ 19 switch(s.charAt(idx)){ 20 case ')': 21 if(stack.isEmpty() || stack.pop() != '('){ 22 return false; 23 } 24 break; 25 case '}': 26 if(stack.isEmpty() || stack.pop() != '{'){ 27 return false; 28 } 29 break; 30 case ']': 31 if(stack.isEmpty() || stack.pop() != '['){ 32 return false; 33 } 34 break; 35 default: 36 stack.push(s.charAt(idx)); 37 break; 38 } 39 idx++; 40 } 41 return stack.isEmpty(); 42 } 43 }
Runtime: O(n), BCR
Space complexity: O(n)
Both runtime and space complexity are optimal.
The following implementation is more concise with fewer duplicated code and easier to change if the input parentheses set has more options.
1 public class Solution { 2 public boolean isValidParentheses(String s) { 3 if(s == null){ 4 return false; 5 } 6 if(s.length() == 0){ 7 return true; 8 } 9 if(s.length() % 2 != 0){ 10 return false; 11 } 12 Stack<Character> stack = new Stack<Character>(); 13 int idx = 0; 14 while(idx < s.length()){ 15 char c = s.charAt(idx); 16 if(")}]".contains(String.valueOf(c))){ 17 if(!stack.isEmpty() && isMatch(stack.peek(), c)){ 18 stack.pop(); 19 } 20 else{ 21 return false; 22 } 23 } 24 else{ 25 stack.push(c); 26 } 27 idx++; 28 } 29 return stack.isEmpty(); 30 } 31 private boolean isMatch(char c1, char c2){ 32 return (c1 == '(' && c2 == ')') || (c1 == '{' && c2 == '}') 33 || (c1 == '[' && c2 == ']'); 34 } 35 }