20. Valid Parentheses#
Difficulty: Easy
Link to Problem: To see the Valid Parentheses problem on LeetCode, click here!
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.
Constraints:
1 <=
s.length
<= \(10^4\)s
consists of parentheses only'()[]{}'
.
def isValid(s):
# Create an empty stack to store opening brackets
stack = []
# Define a mapping for matching brackets
bracket_mapping = {')': '(', '}': '{', ']': '['}
# Iterate through the characters in the input string
for char in s:
# If the character is an opening bracket, push it onto the stack
if char in bracket_mapping.values():
stack.append(char)
# If the character is a closing bracket
elif char in bracket_mapping.keys():
# Pop the top element from the stack if it exists, or use a dummy value '#'
top_element = stack.pop() if stack else '#'
# If the popped element does not match the corresponding opening bracket, return False
if bracket_mapping[char] != top_element:
return False
# If the character is not a bracket, ignore it
# After processing the entire string, if there are any unmatched opening brackets left in the stack, return False
return len(stack) == 0
Explanation:#
We start by defining the
isValid
function that takes a single arguments
, which is the input string containing parentheses and brackets.Inside the function, we create an empty stack, which is a list in Python, to store opening brackets as we encounter them in the input string. The stack will help us keep track of the brackets and their order.
We define a
bracket_mapping
dictionary that maps each closing bracket to its corresponding opening bracket. This mapping will be used to check if a closing bracket matches the most recent opening bracket in the stack.We iterate through each character
char
in the input strings
using afor
loop.If the character
char
is an opening bracket (i.e., it exists in thevalues()
ofbracket_mapping
), we push it onto the stack using theappend()
method.If the character
char
is a closing bracket (i.e., it exists in thekeys()
ofbracket_mapping
), we need to check if it matches the corresponding opening bracket. To do this, we pop the top element from the stack (if it exists) and store it intop_element
. We use a dummy value'#'
if the stack is empty to avoid errors.We then compare
top_element
with the corresponding opening bracket usingbracket_mapping[char]
. If they do not match, it means the string is not valid, and we returnFalse
.If the character
char
is not a bracket, we simply ignore it and continue the loop.After processing the entire string, we check if there are any unmatched opening brackets left in the stack. If the stack is empty, it means all opening brackets have been properly matched and closed, and we return
True
. Otherwise, we returnFalse
.Finally, we provide some test cases at the bottom of the code to demonstrate how the function works for different input strings.
Test cases#
# Example 1:
print(isValid("()"))
True
# Example 2:
print(isValid("()[]{}"))
True
# Example 3:
print(isValid("(]"))
False
Let’s analyze the time and space complexity of the isValid
function:
Time Complexity:
The function iterates through each character in the input string
s
once, performing constant-time operations for each character.Pushing and popping elements from the stack (list) also takes constant time in most cases.
Therefore, the overall time complexity of the function is \(O(n)\), where \(n\) is the length of the input string
s
.
Space Complexity:
The space complexity of the function is determined by the space used by the stack and the
bracket_mapping
dictionary.In the worst case, if the input string
s
consists entirely of opening brackets, the stack can potentially contain all of these opening brackets, resulting in a space complexity of \(O(n)\) in terms of the stack.The
bracket_mapping
dictionary has a constant number of key-value pairs (3 pairs in this case).Therefore, the overall space complexity of the function is \(O(n)\), where \(n\) is the length of the input string
s
, mainly due to the stack space.
In summary:
The time complexity is \(O(n)\) because we iterate through the string once.
The space complexity is \(O(n)\) due to the stack used to keep track of opening brackets.
Challenging Exercises:#
Valid Expressions: Modify the problem to validate not only brackets but also arithmetic expressions containing parentheses, such as “\(2 * (3 + 5) / (4 - 2)\)”.
Valid Parentheses Combinations: Write a function to generate all valid combinations of n pairs of parentheses, where \(n\) is a positive integer. For example, for \(n = 3\), the valid combinations are [“((()))”, “(()())”, “(())()”, “()(())”, “()()()”].