소문자로만 이루어진 문자열 s와 정수 k(오프셋 값)가 주어졌다고 가정해 보겠습니다. 우리가 해결해야 할 문제는 문자열 s의 모든 문자를 알파벳상에서 k칸 뒤에 있는 문자로 치환하는 것입니다. 단, 문자가 'z'를 넘어갈 경우에는 다시 알파벳 처음인 'a'부터 이어지도록 순환(wrap-around) 처리해야 합니다.
예를 들어 입력이 "hello"이고 k = 3이라면, 각 문자가 3칸씩 뒤로 밀려나므로 결과는 "khoor"가 됩니다.
풀이 접근 방법
이 문제는 아래와 같은 단계로 해결할 수 있습니다.
- 하나의 문자
c를 인자로 받는shift()함수를 정의합니다. i := ord(c) - ord('a')— 현재 문자의 알파벳 내 상대적 위치(0~25)를 계산합니다.i := i + k— 위치를k칸만큼 이동시킵니다.i := i mod 26— 26으로 나눈 나머지를 구해, 알파벳 범위를 초과할 경우 자동으로 순환되도록 합니다.chr(ord('a') + i)를 반환하여 최종 문자를 얻습니다.
메인 로직에서는 다음을 수행합니다.
ret: 문자열s의 각 문자c에 대해shift(c)를 호출한 결과들을 연결한 문자열ret을 반환합니다.
구현 예제
아래 파이썬 코드를 통해 더 쉽게 이해할 수 있습니다.
class Solution:
def solve(self, s, k):
def shift(c):
i = ord(c) - ord('a')
i += k
i %= 26
return chr(ord('a') + i)
return "".join(map(shift, s))
ob = Solution()
print(ob.solve("hello", 3))
입력
"hello", 3
출력
khoor
코드 설명 및 복잡도 분석
이 알고리즘의 핵심은 ord()와 chr() 함수를 활용해 문자를 숫자로 변환한 뒤 산술 연산을 수행하고, 다시 문자로 되돌리는 것입니다. 특히 % 26 연산 덕분에 'z'를 넘어가는 경우에도 별도의 조건문 없이 자연스럽게 순환 처리됩니다.
시간 복잡도는 문자열의 길이를 n이라 할 때 O(n)이며, 각 문자를 한 번씩만 처리하면 되기 때문에 매우 효율적입니다. 공간 복잡도 역시 결과 문자열 저장을 위해 O(n)이 필요합니다.