Skip to content

Commit bd6d987

Browse files
committed
feat: add Valid Parentheses
1 parent 6d4d393 commit bd6d987

File tree

7 files changed

+228
-1
lines changed

7 files changed

+228
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"problem_name": "valid_parentheses",
3+
"solution_class_name": "Solution",
4+
"problem_number": "20",
5+
"problem_title": "Valid Parentheses",
6+
"difficulty": "Easy",
7+
"topics": "String, Stack",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given a string `s` containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.\n\nAn input string is valid if:\n\n1. Open brackets must be closed by the same type of brackets.\n2. Open brackets must be closed in the correct order.\n3. Every close bracket has a corresponding open bracket of the same type.",
10+
"readme_examples": [
11+
{ "content": "```\nInput: s = \"()\"\nOutput: true\n```" },
12+
{ "content": "```\nInput: s = \"()[]{}\"\nOutput: true\n```" },
13+
{ "content": "```\nInput: s = \"(]\"\nOutput: false\n```" },
14+
{ "content": "```\nInput: s = \"([])\"\nOutput: true\n```" },
15+
{ "content": "```\nInput: s = \"([)]\"\nOutput: false\n```" }
16+
],
17+
"readme_constraints": "- `1 <= s.length <= 10^4`\n- `s` consists of parentheses only `'()[]{}'`.",
18+
"readme_additional": "",
19+
"solution_imports": "",
20+
"solution_methods": [
21+
{ "name": "is_valid", "parameters": "s: str", "return_type": "bool", "dummy_return": "False" }
22+
],
23+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
24+
"test_class_name": "ValidParentheses",
25+
"test_helper_methods": [
26+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
27+
],
28+
"test_methods": [
29+
{
30+
"name": "test_is_valid",
31+
"parametrize": "s, expected",
32+
"parametrize_typed": "s: str, expected: bool",
33+
"test_cases": "[('()', True), ('()[]{}', True), ('(]', False), ('([])', True), ('([)]', False), ('', True), ('(', False), (')', False), ('{[()]}', True), ('{[(])}', False)]",
34+
"body": "result = self.solution.is_valid(s)\nassert result == expected"
35+
}
36+
],
37+
"playground_imports": "from solution import Solution",
38+
"playground_test_case": "# Example test case\ns = '()'\nexpected = True",
39+
"playground_execution": "result = Solution().is_valid(s)\nresult",
40+
"playground_assertion": "assert result == expected"
41+
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= flood_fill
2+
PROBLEM ?= valid_parentheses
33
FORCE ?= 0
44
COMMA := ,
55

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Valid Parentheses
2+
3+
**Difficulty:** Easy
4+
**Topics:** String, Stack
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 20](https://leetcode.com/problems/valid-parentheses/description/)
8+
9+
## Problem Description
10+
11+
Given a string `s` containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
12+
13+
An input string is valid if:
14+
15+
1. Open brackets must be closed by the same type of brackets.
16+
2. Open brackets must be closed in the correct order.
17+
3. Every close bracket has a corresponding open bracket of the same type.
18+
19+
## Examples
20+
21+
### Example 1:
22+
23+
```
24+
Input: s = "()"
25+
Output: true
26+
```
27+
28+
### Example 2:
29+
30+
```
31+
Input: s = "()[]{}"
32+
Output: true
33+
```
34+
35+
### Example 3:
36+
37+
```
38+
Input: s = "(]"
39+
Output: false
40+
```
41+
42+
### Example 4:
43+
44+
```
45+
Input: s = "([])"
46+
Output: true
47+
```
48+
49+
### Example 5:
50+
51+
```
52+
Input: s = "([)]"
53+
Output: false
54+
```
55+
56+
## Constraints
57+
58+
- `1 <= s.length <= 10^4`
59+
- `s` consists of parentheses only `'()[]{}'`.

leetcode/valid_parentheses/__init__.py

Whitespace-only changes.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"id": "setup",
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"# Example test case\n",
21+
"s = \"()\"\n",
22+
"expected = True"
23+
]
24+
},
25+
{
26+
"cell_type": "code",
27+
"execution_count": null,
28+
"id": "execute",
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"result = Solution().is_valid(s)\nresult"
33+
]
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": null,
38+
"id": "test",
39+
"metadata": {},
40+
"outputs": [],
41+
"source": [
42+
"assert result == expected"
43+
]
44+
}
45+
],
46+
"metadata": {
47+
"kernelspec": {
48+
"display_name": "leetcode-py-py3.13",
49+
"language": "python",
50+
"name": "python3"
51+
},
52+
"language_info": {
53+
"codemirror_mode": {
54+
"name": "ipython",
55+
"version": 3
56+
},
57+
"file_extension": ".py",
58+
"mimetype": "text/x-python",
59+
"name": "python",
60+
"nbconvert_exporter": "python3",
61+
"pygments_lexer": "ipython3",
62+
"version": "3.13.7"
63+
}
64+
},
65+
"nbformat": 4,
66+
"nbformat_minor": 5
67+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
# Time: O(n)
3+
# Space: O(n)
4+
def is_valid(self, s: str) -> bool:
5+
stack = []
6+
pairs = {"(": ")", "[": "]", "{": "}"}
7+
8+
for char in s:
9+
if char in pairs:
10+
stack.append(char)
11+
elif not stack or pairs[stack.pop()] != char:
12+
return False
13+
14+
return not stack
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import pytest
2+
3+
from leetcode_py.test_utils import logged_test
4+
5+
from .solution import Solution
6+
7+
8+
class TestValidParentheses:
9+
def setup_method(self):
10+
self.solution = Solution()
11+
12+
@pytest.mark.parametrize(
13+
"s, expected",
14+
[
15+
("()", True),
16+
("()[]{}", True),
17+
("(]", False),
18+
("([])", True),
19+
("([)]", False),
20+
("", True),
21+
("(", False),
22+
(")", False),
23+
("{[()]}", True),
24+
("{[(])}", False),
25+
("(((", False),
26+
(")))", False),
27+
("()()()", True),
28+
("({[]})", True),
29+
("({[}])", False),
30+
("[[[[[]]]]]", True),
31+
("[[[[[]]]]", False),
32+
("{{{{{}}}}}", True),
33+
("((((((((((", False),
34+
("))))))))))", False),
35+
("(){}[]", True),
36+
("([{}])", True),
37+
("([{]})", False),
38+
("(())", True),
39+
("(()", False),
40+
("())", False),
41+
],
42+
)
43+
@logged_test
44+
def test_is_valid(self, s: str, expected: bool):
45+
result = self.solution.is_valid(s)
46+
assert result == expected

0 commit comments

Comments
 (0)