Skip to content

Commit c18ec80

Browse files
committed
solve(w15): 5. Longest Palindromic Substring
1 parent 2cbac12 commit c18ec80

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# https://leetcode.com/problems/longest-palindromic-substring/
2+
3+
class Solution:
4+
def longestPalindrome_dp(self, s: str) -> str:
5+
"""
6+
[Complexity]
7+
- TC: O(n^2)
8+
- SC: O(n^2)
9+
10+
[Approach]
11+
(1) lo == hi: len 1짜리 substring -> True
12+
(2) lo + 1 == hi: len 2짜리 substring -> s[lo] == s[hi]
13+
(3) 그 외: (a) 내부 string인 s[lo + 1] ~ s[hi - 1]이 palindrome이면서,
14+
(b) s[lo] == s[hi]이면 True
15+
16+
=> (3-a)로 인해 2D DP를 사용할 수 있으며 (dp[lo][hi] = s[lo] ~ s[hi]가 palindrome인지 여부),
17+
dp[lo + 1][hi - 1]을 살펴봐야 하므로 lo는 **오른쪽부터 거꾸로 순회**해야 한다. (dp[lo][..]를 채우기 위해 dp[lo + 1][..]을 봐야 함)
18+
"""
19+
20+
n = len(s)
21+
res_lo = res_hi = 0
22+
dp = [[False] * n for _ in range(n)]
23+
24+
# early stop
25+
if n < 2 or s == s[::-1]:
26+
return s
27+
28+
for lo in range(n - 1, -1, -1):
29+
for hi in range(lo, n):
30+
# (1) lo == hi
31+
if lo == hi:
32+
dp[lo][hi] = True
33+
34+
# (2) lo + 1 == hi
35+
elif lo + 1 == hi:
36+
dp[lo][hi] = s[lo] == s[hi]
37+
38+
# (3) otherwise (a) dp[lo + 1][hi - 1] && (b) s[lo] == s[hi]
39+
else:
40+
dp[lo][hi] = dp[lo + 1][hi - 1] and s[lo] == s[hi]
41+
42+
# update res (s[lo:hi + 1]가 palindrome이면서, 최대 길이인 경우)
43+
if dp[lo][hi] and res_hi - res_lo < hi - lo:
44+
res_lo, res_hi = lo, hi
45+
46+
return s[res_lo:res_hi + 1]
47+
48+
def longestPalindrome(self, s: str) -> str:
49+
"""
50+
[Complexity]
51+
- TC: O(n^2) (각 center에서 양쪽으로 expand)
52+
- SC: O(1)
53+
54+
[Approach]
55+
palindrome은 다음의 두 케이스로 구분되므로, two-pointer로도 풀 수 있다.
56+
(1) substring 길이가 홀수: 가운데 원소는 확인할 필요 X
57+
(2) substring 길이가 짝수: 모두 확인
58+
"""
59+
60+
n, res_lo, max_len = len(s), 0, 1
61+
62+
# early stop
63+
if n < 2 or s == s[::-1]:
64+
return s
65+
66+
# expanding from center
67+
def expand(lo, hi):
68+
# 양쪽으로 1씩 늘려가며 가장 긴 palindrome 찾기
69+
while lo >= 0 and hi < n and s[lo] == s[hi]:
70+
lo -= 1
71+
hi += 1
72+
return lo + 1, hi # s[lo + 1:hi]
73+
74+
# 모든 위치에서 (1) 홀수 길이 palindrome, (2) 짝수 길이 palindrome의 max len 값 찾기
75+
for i in range(n - 1):
76+
# 홀수 길이 팰린드롬 (중심이 i)
77+
lo1, hi1 = expand(i, i)
78+
if hi1 - lo1 > max_len:
79+
res_lo = lo1
80+
max_len = hi1 - lo1
81+
82+
# 짝수 길이 팰린드롬 (중심이 i, i+1)
83+
lo2, hi2 = expand(i, i + 1)
84+
if hi2 - lo2 > max_len:
85+
res_lo = lo2
86+
max_len = hi2 - lo2
87+
88+
return s[res_lo:res_lo + max_len]

0 commit comments

Comments
 (0)