[알고리즘 소개]
전체 문자열에서 회문의 개수 및 길이를 구하는 알고리즘
[코딩 방법]
- 현재 시점에서 최대 길이 회문의 인덱스 c, 최대 길이 회문의 최고 인덱스 r, 그리고 i번째를 중심으로 하는 회문의 반지름 P[i]
- 짝수 회문도 검사하기 위해 문자열 사이사이에 문자 삽입 (ex. abcde → #a#b#c#d#e#)
- 반복문을 돌면서 i > r 이라면 P[i] = 0,
else라면 가장 긴 회문 안에 현재 인덱스가 들어 있는 것이므로 대칭인 P'[i]( = P[2 * c - i] )에 대해 P[i] == P'[i]임이 보장됨. 즉, P[i] = P'[i]가 되어야 하지만, r안에 들어와 있어야만 P[i] == P'[i]가 보장되므로 P[i] = min(P'[i], r - i) - P[i]의 초기값을 빠르게 구했으므로 이제는 직접 비교하면서 P[i]를 증가.
while (i + P[i] + 1 < (최대 길이) && i - P[i] - 1 > -1 && s[i + P[i] + 1] == s[i - P[i] - 1]) ++P[i] - 과정 4까지 마쳤으면 i를 중심으로 하는 회문의 최대 길이는 i + P[i]이므로 i + P[i] > r이라면 r과 c갱신 필요.
r = i + P[i], c = i
[시간 복잡도]
$O(N)$
[공부용 링크]
https://blog.naver.com/PostView.nhn?blogId=jqkt15&logNo=222108415284
'정리 > 알고리즘' 카테고리의 다른 글
[알고리즘] 이분매칭 (0) | 2023.03.20 |
---|---|
[알고리즘] 쾨닉의 정리 (Kőnig's theorem) (0) | 2023.02.27 |
[알고리즘] KMP (0) | 2023.02.05 |
[알고리즘] 이분 탐색 (Binary Search) (0) | 2023.01.15 |
[알고리즘] 크루스칼 (Kruskal) (0) | 2021.04.05 |