Skip to content

Commit 410e3f8

Browse files
committed
feat: add problem 131 palindrome partitioning
1 parent c96f647 commit 410e3f8

File tree

7 files changed

+225
-0
lines changed

7 files changed

+225
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Palindrome Partitioning
2+
3+
**Difficulty:** Medium
4+
**Topics:** String, Dynamic Programming, Backtracking
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 131](https://leetcode.com/problems/palindrome-partitioning/description/)
8+
9+
## Problem Description
10+
11+
Given a string `s`, partition `s` such that every substring of the partition is a **palindrome**. Return _all possible palindrome partitioning of `s`_.
12+
13+
## Examples
14+
15+
### Example 1:
16+
17+
```
18+
Input: s = "aab"
19+
Output: [["a","a","b"],["aa","b"]]
20+
```
21+
22+
### Example 2:
23+
24+
```
25+
Input: s = "a"
26+
Output: [["a"]]
27+
```
28+
29+
## Constraints
30+
31+
- `1 <= s.length <= 16`
32+
- `s` contains only lowercase English letters.

leetcode/palindrome_partitioning/__init__.py

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def run_partition(solution_class: type, s: str):
2+
implementation = solution_class()
3+
return implementation.partition(s)
4+
5+
6+
def assert_partition(result: list[list[str]], expected: list[list[str]]) -> bool:
7+
# Sort inner lists and outer list for comparison
8+
# Note: Inner lists are partitions (lists of strings), order of partitions doesn't matter
9+
# Order of strings within a partition DOES matter (it must reconstruct s)
10+
# But wait, the problem says "partition s", so the order of substrings must match the order in s.
11+
# So we only need to sort the outer list of partitions.
12+
result_sorted = sorted(result)
13+
expected_sorted = sorted(expected)
14+
assert result_sorted == expected_sorted
15+
return True
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from helpers import assert_partition, run_partition\n",
11+
"from solution import Solution"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"id": "setup",
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"# Example test case\n",
22+
"s = \"aab\"\n",
23+
"expected = [[\"a\", \"a\", \"b\"], [\"aa\", \"b\"]]"
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": null,
29+
"id": "run",
30+
"metadata": {},
31+
"outputs": [],
32+
"source": [
33+
"result = run_partition(Solution, s)\n",
34+
"result"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": null,
40+
"id": "assert",
41+
"metadata": {},
42+
"outputs": [],
43+
"source": [
44+
"assert_partition(result, expected)"
45+
]
46+
}
47+
],
48+
"metadata": {
49+
"kernelspec": {
50+
"display_name": "leetcode-py-py3.13",
51+
"language": "python",
52+
"name": "python3"
53+
},
54+
"language_info": {
55+
"codemirror_mode": {
56+
"name": "ipython",
57+
"version": 3
58+
},
59+
"file_extension": ".py",
60+
"mimetype": "text/x-python",
61+
"name": "python",
62+
"nbconvert_exporter": "python3",
63+
"version": "3.13.7"
64+
}
65+
},
66+
"nbformat": 4,
67+
"nbformat_minor": 5
68+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution:
2+
# Time: O(N * 2^N)
3+
# Space: O(N)
4+
def partition(self, s: str) -> list[list[str]]:
5+
result: list[list[str]] = []
6+
self._backtrack(s, 0, [], result)
7+
return result
8+
9+
def _backtrack(self, s: str, start: int, path: list[str], result: list[list[str]]) -> None:
10+
if start == len(s):
11+
result.append(path[:])
12+
return
13+
14+
for end in range(start + 1, len(s) + 1):
15+
substring = s[start:end]
16+
if self._is_palindrome(substring):
17+
path.append(substring)
18+
self._backtrack(s, end, path, result)
19+
path.pop()
20+
21+
def _is_palindrome(self, s: str) -> bool:
22+
return s == s[::-1]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import pytest
2+
3+
from leetcode_py import logged_test
4+
5+
from .helpers import assert_partition, run_partition
6+
from .solution import Solution
7+
8+
9+
class TestPalindromePartitioning:
10+
def setup_method(self):
11+
self.solution = Solution()
12+
13+
@logged_test
14+
@pytest.mark.parametrize("s, expected", [("aab", [["a", "a", "b"], ["aa", "b"]]), ("a", [["a"]])])
15+
def test_partition(self, s: str, expected: list[list[str]]):
16+
result = run_partition(Solution, s)
17+
assert_partition(result, expected)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"problem_name": "palindrome_partitioning",
3+
"solution_class_name": "Solution",
4+
"problem_number": "131",
5+
"problem_title": "Palindrome Partitioning",
6+
"difficulty": "Medium",
7+
"topics": "String, Dynamic Programming, Backtracking",
8+
"readme_description": "Given a string `s`, partition `s` such that every substring of the partition is a **palindrome**. Return *all possible palindrome partitioning of `s`*.",
9+
"_readme_examples": {
10+
"list": [
11+
{
12+
"content": "```\nInput: s = \"aab\"\nOutput: [[\"a\",\"a\",\"b\"],[\"aa\",\"b\"]]\n```"
13+
},
14+
{
15+
"content": "```\nInput: s = \"a\"\nOutput: [[\"a\"]]\n```"
16+
}
17+
]
18+
},
19+
"readme_constraints": "- `1 <= s.length <= 16`\n- `s` contains only lowercase English letters.",
20+
"readme_additional": "",
21+
"helpers_imports": "",
22+
"helpers_content": "",
23+
"helpers_run_name": "partition",
24+
"helpers_run_signature": "(solution_class: type, s: str)",
25+
"helpers_run_body": " implementation = solution_class()\n return implementation.partition(s)",
26+
"helpers_assert_name": "partition",
27+
"helpers_assert_signature": "(result: list[list[str]], expected: list[list[str]]) -> bool",
28+
"helpers_assert_body": " # Sort inner lists and outer list for comparison\n # Note: Inner lists are partitions (lists of strings), order of partitions doesn't matter\n # Order of strings within a partition DOES matter (it must reconstruct s)\n # But wait, the problem says \"partition s\", so the order of substrings must match the order in s.\n # So we only need to sort the outer list of partitions.\n result_sorted = sorted(result)\n expected_sorted = sorted(expected)\n assert result_sorted == expected_sorted\n return True",
29+
"solution_imports": "",
30+
"solution_contents": "",
31+
"solution_class_content": "",
32+
"test_imports": "import pytest\nfrom leetcode_py import logged_test\nfrom .helpers import assert_partition, run_partition\nfrom .solution import Solution",
33+
"test_content": "",
34+
"test_class_name": "PalindromePartitioning",
35+
"test_class_content": " def setup_method(self):\n self.solution = Solution()",
36+
"_solution_methods": {
37+
"list": [
38+
{
39+
"name": "partition",
40+
"signature": "(self, s: str) -> list[list[str]]",
41+
"body": " # TODO: Implement partition\n return []"
42+
}
43+
]
44+
},
45+
"_test_helper_methods": {
46+
"list": [
47+
{
48+
"name": "setup_method",
49+
"parameters": "",
50+
"body": "self.solution = Solution()"
51+
}
52+
]
53+
},
54+
"_test_methods": {
55+
"list": [
56+
{
57+
"name": "test_partition",
58+
"signature": "(self, s: str, expected: list[list[str]])",
59+
"parametrize": "s, expected",
60+
"test_cases": {
61+
"list": ["('aab', [['a', 'a', 'b'], ['aa', 'b']])", "('a', [['a']])"]
62+
},
63+
"body": " result = run_partition(Solution, s)\n assert_partition(result, expected)"
64+
}
65+
]
66+
},
67+
"playground_imports": "from helpers import run_partition, assert_partition\nfrom solution import Solution",
68+
"playground_setup": "# Example test case\ns = 'aab'\nexpected = [['a', 'a', 'b'], ['aa', 'b']]",
69+
"playground_run": "result = run_partition(Solution, s)\nresult",
70+
"playground_assert": "assert_partition(result, expected)"
71+
}

0 commit comments

Comments
 (0)