---
# System prepended metadata

title: 20. Valid Parentheses
tags: [leetcode]

---

###### 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 == []
```