Skip to content

Commit 12f1c68

Browse files
committed
palindromic substrings solution (py)
1 parent 59632e8 commit 12f1c68

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""
2+
string s가 주어졌을 때, s에서 나올 수 있는 palindrome의 조건을 만족하는 substring 개수를 구하라.
3+
(s는 전부 소문자, 1이상 1000이하)
4+
5+
1. 완전 탐색
6+
- 나올 수 있는 모든 경우의 수 substring을 만들어 palindrome의 조건을 만족하는지 계산
7+
8+
TC: O(N^3)
9+
SC: O(N)
10+
11+
2. 최적화 - 중심 확장
12+
- 모든 palindrome은 어떤 중심을 기준으로 좌우 대칭인 원리를 이용
13+
=> 문자열의 모든 위치를 중심으로 삼고, 양쪽으로 좌우를 확장하며 검사하면 됨
14+
- 중심 개수: 2n - 1
15+
16+
TC: O(N^2)
17+
SC: O(1)
18+
19+
3. 최적화 - DP
20+
1. 길이 1인 문자열은 항상 팰린드롬
21+
dp[i][i] = True
22+
2. 길이 2인 문자열은 두 문자가 같으면 팰린드롬
23+
s[i] == s[i+1] -> dp[i][i+1] = True
24+
3. 길이 3 이상인 문자열은 끝 두 문자열이 같고 안에 문자열도 모두 같아야 팰린드롬
25+
s[i] == s[j] and dp[i+1][j-1] == True -> dp[i][j] = True
26+
(dp[i+1][j-1] == True시, s[i+1...j-1] 구간의 문자열이 이미 팰린드롬이라는 뜻)
27+
28+
TC: O(N^2)
29+
SC: O(N^2)
30+
"""
31+
32+
# 완전 탐색 풀이
33+
class Solution:
34+
def countSubstrings(self, s: str) -> int:
35+
cnt = 0
36+
n = len(s)
37+
38+
def isPalindrome(test):
39+
return test == test[::-1]
40+
41+
for i in range(n):
42+
for j in range(i+1, n+1):
43+
if isPalindrome(s[i:j]):
44+
cnt += 1
45+
46+
return cnt
47+
48+
# 최적화 - 중심 확장 풀이
49+
class Solution:
50+
def countSubstrings(self, s: str) -> int:
51+
cnt = 0
52+
n = len(s)
53+
54+
def expandAroundCenter(left: int, right: int):
55+
nonlocal cnt # 중첩 함수에서 바깥 함수의 지역 변수에 접근할 때 사용
56+
while left >= 0 and right < n and s[left] == s[right]: # 범위를 벗어나지 않고, 팰린드롬 조건을 충족하면
57+
# 확장
58+
cnt += 1
59+
left -= 1
60+
right += 1
61+
62+
for center in range(n):
63+
expandAroundCenter(center, center) # 홀수 길이
64+
expandAroundCenter(center, center + 1) # 짝수 길이
65+
66+
return cnt
67+
68+
# 최적화 - DP 풀이
69+
class Solution:
70+
def countSubstrings(self, s: str) -> int:
71+
cnt = 0
72+
n = len(s)
73+
dp = [[False] * n for _ in range(n)]
74+
75+
# 길이 1 => 항상 팰린드롬
76+
for i in range(n):
77+
dp[i][i] = True
78+
cnt += 1
79+
80+
# 길이 2 => 같은 문자면 팰린드롬
81+
for i in range(n-1):
82+
if s[i] == s[i+1]: # 서로 같은 문자면
83+
dp[i][i+1] = True # 팰린드롬
84+
cnt += 1
85+
86+
# 길이 3 이상
87+
for length in range(3, n+1): # length는 부분 문자열의 길이
88+
for i in range(n - length + 1):
89+
j = i + length - 1 # 끝 인덱스
90+
if s[i] == s[j] and dp[i+1][j-1]:
91+
dp[i][j] = True
92+
cnt += 1
93+
94+
return cnt

0 commit comments

Comments
 (0)