Skip to content

Commit 30ff8f5

Browse files
committed
LeetCode 131. Palindrome Partitioning
1 parent 37cff41 commit 30ff8f5

File tree

4 files changed

+92
-14
lines changed

4 files changed

+92
-14
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
106106
| [127. Word Ladder][lc127] | 🔴 Hard | [![python](res/py.png)][lc127py] |
107107
| [128. Longest Consecutive Sequence][lc128] | 🟠 Medium | [![python](res/py.png)][lc128py] |
108108
| [130. Surrounded Regions][lc130] | 🟠 Medium | [![python](res/py.png)][lc130py] |
109+
| [131. Palindrome Partitioning][lc131] | 🟠 Medium | [![python](res/py.png)][lc131py] |
109110
| [133. Clone Graph][lc133] | 🟠 Medium | [![python](res/py.png)][lc133py] |
110111
| [134. Gas Station][lc134] | 🟠 Medium | [![python](res/py.png)][lc134py] |
111112
| [135. Candy][lc135] | 🔴 Hard | [![python](res/py.png)][lc135py] |
@@ -574,6 +575,8 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
574575
[lc128py]: leetcode/longest-consecutive-sequence.py
575576
[lc130]: https://leetcode.com/problems/surrounded-regions/
576577
[lc130py]: leetcode/surrounded-regions.py
578+
[lc131]: https://leetcode.com/problems/palindrome-partitioning/
579+
[lc131py]: leetcode/palindrome-partitioning.py
577580
[lc133]: https://leetcode.com/problems/clone-graph/
578581
[lc133py]: leetcode/clone-graph.py
579582
[lc134]: https://leetcode.com/problems/gas-station/

leetcode/lists/dp.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ tracking your own progress.
339339
| | Level | Name | Solutions |
340340
| :-: | --------- | ------------------------------------------------------------------------- | --------------------------------------- |
341341
|| 🟢 Easy | [392. Is Subsequence][lc392] | [![python](../../res/py.png)][lc392py] |
342-
| | 🟠 Medium | [131. Palindrome Partitioning][lc131] | |
342+
| | 🟠 Medium | [131. Palindrome Partitioning][lc131] | [![python](../../res/py.png)][lc131py] |
343343
|| 🟠 Medium | [139. Word Break][lc139] | [![python](../../res/py.png)][lc139py] |
344344
| | 🟠 Medium | [467. Unique Substrings in Wraparound String][lc467] | |
345345
| | 🟠 Medium | [712. Minimum ASCII Delete Sum for Two Strings][lc712] | |
@@ -362,6 +362,7 @@ tracking your own progress.
362362
[lc392]: https://leetcode.com/problems/is-subsequence/
363363
[lc392py]: ../is-subsequence.py
364364
[lc131]: https://leetcode.com/problems/palindrome-partitioning/
365+
[lc131py]: ../palindrome-partitioning.py
365366
[lc139]: https://leetcode.com/problems/word-break/
366367
[lc139py]: ../word-break.py
367368
[lc467]: https://leetcode.com/problems/unique-substrings-in-wraparound-string/

leetcode/lists/neetcode.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ From their website:
1111
> Get stuck? I've created a thorough 🎥 video explanation for each problem.
1212
1313
- [Neetcode categorized list of problems](#neetcode-categorized-list-of-problems)
14-
- [Arrays & Hashing](#arrays--hashing)
14+
- [Arrays \& Hashing](#arrays--hashing)
1515
- [Two Pointers](#two-pointers)
1616
- [Sliding Window](#sliding-window)
1717
- [Stack](#stack)
@@ -27,7 +27,7 @@ From their website:
2727
- [2-D Dynamic Programming](#2-d-dynamic-programming)
2828
- [Greedy](#greedy)
2929
- [Intervals](#intervals)
30-
- [Math & Geometry](#math--geometry)
30+
- [Math \& Geometry](#math--geometry)
3131
- [Bit Manipulation](#bit-manipulation)
3232

3333
## Arrays & Hashing
@@ -297,17 +297,17 @@ From their website:
297297

298298
## Backtracking
299299

300-
| | B75 | Level | Problem | Solutions |
301-
| :-: | --- | --------- | ------------------------------------------------- | ------------------------------------- |
302-
|| | 🟠 Medium | [78. Subsets][lc78] | [![python](../../res/py.png)][lc78py] |
303-
|| | 🟠 Medium | [39. Combination Sum][lc39] | [![python](../../res/py.png)][lc39py] |
304-
|| | 🟠 Medium | [46. Permutations][lc46] | [![python](../../res/py.png)][lc46py] |
305-
|| | 🟠 Medium | [90. Subsets II][lc90] | [![python](../../res/py.png)][lc90py] |
306-
||| 🟠 Medium | [40. Combination Sum II][lc40] | [![python](../../res/py.png)][lc40py] |
307-
||| 🟠 Medium | [79. Word Search][lc79] | [![python](../../res/py.png)][lc79py] |
308-
| | | 🟠 Medium | [131. Palindrome Partitioning][lc131] | |
309-
|| | 🟠 Medium | [17. Letter Combinations of a Phone Number][lc17] | [![python](../../res/py.png)][lc17py] |
310-
|| | 🔴 Hard | [51. N-Queens][lc51] | [![python](../../res/py.png)][lc51py] |
300+
| | B75 | Level | Problem | Solutions |
301+
| :-: | --- | --------- | ------------------------------------------------- | -------------------------------------- |
302+
|| | 🟠 Medium | [78. Subsets][lc78] | [![python](../../res/py.png)][lc78py] |
303+
|| | 🟠 Medium | [39. Combination Sum][lc39] | [![python](../../res/py.png)][lc39py] |
304+
|| | 🟠 Medium | [46. Permutations][lc46] | [![python](../../res/py.png)][lc46py] |
305+
|| | 🟠 Medium | [90. Subsets II][lc90] | [![python](../../res/py.png)][lc90py] |
306+
||| 🟠 Medium | [40. Combination Sum II][lc40] | [![python](../../res/py.png)][lc40py] |
307+
||| 🟠 Medium | [79. Word Search][lc79] | [![python](../../res/py.png)][lc79py] |
308+
| | | 🟠 Medium | [131. Palindrome Partitioning][lc131] | [![python](../../res/py.png)][lc131py] |
309+
|| | 🟠 Medium | [17. Letter Combinations of a Phone Number][lc17] | [![python](../../res/py.png)][lc17py] |
310+
|| | 🔴 Hard | [51. N-Queens][lc51] | [![python](../../res/py.png)][lc51py] |
311311

312312
[lc78]: https://leetcode.com/problems/subsets/
313313
[lc78py]: ../subsets.py
@@ -322,6 +322,7 @@ From their website:
322322
[lc79]: https://leetcode.com/problems/word-search/
323323
[lc79py]: https://leetcode.com/problems/word-search/
324324
[lc131]: https://leetcode.com/problems/palindrome-partitioning/
325+
[lc131py]: ../palindrome-partitioning.py
325326
[lc17]: https://leetcode.com/problems/letter-combinations-of-a-phone-number/
326327
[lc17py]: ../letter-combinations-of-a-phone-number.py
327328
[lc51]: https://leetcode.com/problems/n-queens/

leetcode/palindrome-partitioning.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# 131. Palindrome Partitioning
2+
# 🟠 Medium
3+
#
4+
# https://leetcode.com/problems/palindrome-partitioning/
5+
#
6+
# Tags: String - Dynamic Programming - Backtracking
7+
8+
import timeit
9+
from typing import List
10+
11+
# Classic backtracking solution, for each index, we try all string
12+
# prefixes to see if they are a palindrome, if they are, we use them to
13+
# build one of the solutions (one of the ways to partition the input
14+
# string) and keep building starting at the first unused index.
15+
#
16+
# Time complexity: O(n*2^n) - The decision tree splits in 2 at each
17+
# level, and there are n levels where n is the number of characters in
18+
# the input string. At each call, we iterate over all characters in
19+
# the substring, which could also be n, to check if the substring is
20+
# a palindrome.
21+
# Space complexity: O(n) - The height of the call stack, if we take into
22+
# consideration the result, then n^2 which is the possible number of
23+
# palindromes.
24+
#
25+
# Runtime 658 ms Beats 85.74%
26+
# Memory 30.3 MB Beats 47.4%
27+
class Solution:
28+
def partition(self, s: str) -> List[List[str]]:
29+
res, current = [], []
30+
# The first index that we need to look into.
31+
def bt(idx: int) -> None:
32+
if idx == len(s):
33+
res.append(current[:])
34+
# Try to form palindromes of all lengths starting at the
35+
# given index.
36+
for i in range(idx, len(s)):
37+
# Try to form a palindrome with i + 1 characters.
38+
sub = s[idx : i + 1]
39+
# If this substring is not a palindrome, ignore it.
40+
if sub == sub[::-1]:
41+
current.append(sub)
42+
bt(i + 1)
43+
current.pop()
44+
45+
bt(0)
46+
return res
47+
48+
49+
def test():
50+
executors = [Solution]
51+
tests = [
52+
["a", [["a"]]],
53+
["aab", [["a", "a", "b"], ["aa", "b"]]],
54+
]
55+
for executor in executors:
56+
start = timeit.default_timer()
57+
for _ in range(1):
58+
for col, t in enumerate(tests):
59+
sol = executor()
60+
result = sol.partition(t[0])
61+
exp = t[1]
62+
assert result == exp, (
63+
f"\033[93m» {result} <> {exp}\033[91m for"
64+
+ f" test {col} using \033[1m{executor.__name__}"
65+
)
66+
stop = timeit.default_timer()
67+
used = str(round(stop - start, 5))
68+
cols = "{0:20}{1:10}{2:10}"
69+
res = cols.format(executor.__name__, used, "seconds")
70+
print(f"\033[92m» {res}\033[0m")
71+
72+
73+
test()

0 commit comments

Comments
 (0)