###### tags: `leetcode`
# 20. Valid Parentheses
### Size
use `int` instead of `char` to in the stack
```python=
>>> sys.getsizeof(1)
28
>>> sys.getsizeof('a')
50
```
### Geometry Interpretation
- Let (, [, { stand for -x, -y, -z,
Let ), ], } stand for +x, +y, +z,
- Start from (0,0,0). End at (0,0,0).
- We can go toward -x/-y/-z or go back along the same path
- At (0,0,0), there is no previous path, so we can only go -x/-y/-z.
- Going back will erase the path.
## Stack Approach
Already good in space.
:::info
Runtime: 24 ms, faster than 97.46% of Python3 online submissions for Valid Parentheses.
Memory Usage: 12.6 MB, less than 100.00% of Python3 online submissions for Valid Parentheses.
:::
```python=
class Solution:
def isValid(self, s: str) -> bool:
# three 1-dimensional walks
# No ! It is more complicated than three independent 1-dimensional walks.
# Note that "([)]" is illegal.
# This is a 3D walk.
# We can only proceed by x-=1 or y-=1 or z-=1.
# Or we can go back on the same path
stack = []
for char in s:
# I use 1,2,3 instead of '(','[','{' because they 1,2,3 is smaller in size
if '(' == char:
stack.append(1)
if '[' == char:
stack.append(2)
if '{' == char:
stack.append(3)
if ')' == char:
if stack:
if stack[-1] == 1:
stack.pop()
else:
return False
else:
return False
if ']' == char:
if stack:
if stack[-1] == 2:
stack.pop()
else:
return False
else:
return False
if '}' == char:
if stack:
if stack[-1] == 3:
stack.pop()
else:
return False
else:
return False
if stack == []:
return True
else:
return False
```
### Revision, using `elif` and `return stack==[]`
:::info
Runtime: 28 ms, faster than 91.84% of Python3 online submissions for Valid Parentheses.
Memory Usage: 12.8 MB, less than 100.00% of Python3 online submissions for Valid Parentheses..
:::
```python=
def isValid(self, s: str) -> bool:
stack = []
for char in s:
if '(' == char:
stack.append(1)
if '[' == char:
stack.append(2)
if '{' == char:
stack.append(3)
if ')' == char:
if stack == []:
return False
elif stack[-1] == 1:
stack.pop()
else:
return False
if ']' == char:
if stack == []:
return False
elif stack[-1] == 2:
stack.pop()
else:
return False
if '}' == char:
if stack == []:
return False
elif stack[-1] == 3:
stack.pop()
else:
return False
return stack == []
```
### Further Revision, if the first condition fails, the second will not be judged
:::info
```python=
if ')' == char:
if stack == []:
return False
elif stack[-1] == 1:
stack.pop()
else:
return False
```
can be reduced to
```python=
if ')' == char:
if stack and stack[-1] == 1:
stack.pop()
else:
return False
```
:::
```python=
def isValid(self, s: str) -> bool:
stack = []
for char in s:
if '(' == char:
stack.append(1)
if '[' == char:
stack.append(2)
if '{' == char:
stack.append(3)
if ')' == char:
if stack and stack[-1] == 1:
stack.pop()
else:
return False
if ']' == char:
if stack and stack[-1] == 2:
stack.pop()
else:
return False
if '}' == char:
if stack and stack[-1] == 3:
stack.pop()
else:
return False
return stack == []
```
### me, after 2 months
```python=
def isValid(self, s: str) -> bool:
st = []
for ele in s:
if ele == '(' or ele == '{' or ele == '[':
st.append(ele)
if ele == ')':
if st and st[-1] == '(':
st.pop()
else:
return False
if ele == '}':
if st and st[-1] == '{':
st.pop()
else:
return False
if ele == ']':
if st and st[-1] == '[':
st.pop()
else:
return False
if st == []:
return True
return False
```
## Solution, `map {}`
A dummy element `'#'`
Easy to have more types of bracket.
```python=
class Solution(object):
def isValid(self, s):
# The stack to keep track of opening brackets.
stack = []
# Hash map for keeping track of mappings. This keeps the code very clean.
# Also makes adding more types of parenthesis easier
mapping = {')': '(', '}': '{', ']': '['}
# For every bracket in the expression.
for char in s:
# If the character is an closing bracket
if char in mapping:
# Pop the topmost element from the stack, if it is non empty
# Otherwise assign a dummy value of '#' to the top_element variable
top_element = stack.pop() if stack else '#'
# The mapping for the opening bracket in our hash and the top
# element of the stack don't match, return False
if mapping[char] != top_element:
return False
else:
# We have an opening bracket, simply push it onto the stack.
stack.append(char)
# In the end, if the stack is empty, then we have a valid expression.
# The stack won't be empty for cases like ((()
return not stack
```
## Concise
Though not very efficient.
```python=
def isValid(self, s):
while '()' in s or '{}' in s or '[]' in s:
s = s.replace('()', '').replace('{}', '').replace('[]', '')
return s == ''
```
## h2
GOOD! `stack and i == bracket_map[stack[-1]]:`
```python=
def isValid(self, s):
bracket_map = {'(': ')', '[': ']', '{': '}'}
stack = []
for i in s:
if i in bracket_map:
stack.append(i)
elif stack and i == bracket_map[stack[-1]]: # !!!
stack.pop()
else:
return False
return stack == []
```