Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python으로 문자열의 회문 부분 문자열 개수 구하기

문제 개요

소문자(ASCII 문자)로만 이루어진 문자열이 주어졌을 때, 해당 문자열 안에서 회문(palindrome)이 되는 연속된 부분 문자열이 모두 몇 개 있는지 찾는 문제입니다.

예를 들어 입력 문자열이 "level"이라면 출력은 7이 됩니다. ['level', 'eve', 'l', 'e', 'v', 'e', 'l']과 같이 일곱 개의 회문 부분 문자열이 존재하기 때문입니다.

해결 알고리즘

이 문제는 다음 단계를 따라 해결할 수 있습니다.

  • N := 26 (알파벳 개수)
  • n := 문자열의 길이
  • sum := 0 (결과를 저장할 변수)
  • my_map := 크기가 N인 리스트를 생성하고 0으로 초기화
  • i를 0부터 n-1까지 반복:
    • my_map[(str[i]의 아스키 코드) - ('a'의 아스키 코드)] 값을 1씩 증가시켜 각 문자의 등장 횟수를 계산
  • i를 0부터 N-1까지 반복:
    • my_map[i]가 0이 아니라면, sum에 (my_map[i] × (my_map[i] + 1)) / 2를 더함
  • 최종적으로 sum을 반환

여기서 핵심은 각 문자별 등장 횟수를 센 뒤, k번 등장한 문자에 대해 k × (k + 1) / 2 공식을 적용해 가능한 조합의 수를 더하는 것입니다.

구현 예제

아래 코드를 통해 실제 동작을 확인해 보겠습니다.

N = 26

def all_palindrome_substr_count(str):
    n = len(str)
    sum = 0
    my_map = [0] * N
    
    for i in range(n):
        my_map[ord(str[i]) - ord('a')] += 1
    
    for i in range(N):
        if my_map[i]:
            sum += (my_map[i] * (my_map[i] + 1) // 2)
    
    return sum

str = "level"
print(all_palindrome_substr_count(str))

입력

"level"

출력

7

마무리

이 방법은 문자열을 한 번만 순회하면서 각 문자의 빈도를 기록하므로 시간 복잡도는 O(n)입니다. 추가적인 자료구조 없이 크기 26의 배열만 사용하기 때문에 메모리 효율성도 우수하며, 소문자 알파벳으로 구성된 문자열에서 회문 부분 문자열의 개수를 빠르게 계산할 수 있습니다.