문제 소개
하나의 문자열과 정수 k가 주어졌을 때, 문자열의 시작부터 세어 매 2k개의 문자 구간마다 그중 앞의 k개 문자를 뒤집는 것이 이번 문제의 목표입니다. 다만 문자열 끝에 도달했을 때 남은 문자 수에 따라 처리 방식이 달라집니다.
- 남은 문자가 k개보다 적다면 → 남은 문자를 모두 뒤집습니다.
- 남은 문자가 k개 이상 2k개 미만이라면 → 앞의 k개만 뒤집고 나머지는 원래 순서대로 둡니다.
예를 들어 입력이 "abcdefgh"이고 k = 3이라면, 첫 세 글자 "abc"가 "cba"로 뒤집히고, 가운데 "def"는 그대로 유지되며, 마지막에 남은 두 글자 "gh"는 k개 미만이므로 모두 뒤집혀 "hg"가 됩니다. 따라서 최종 결과는 "cbadefhg"입니다.
해결 접근 방법
문자열을 문자 단위 리스트로 변환한 뒤, 2k 간격으로 블록을 이동시키며 해당 구간만 슬라이싱해 뒤집는 방식으로 해결할 수 있습니다. 단계별로 정리하면 다음과 같습니다.
- 문자열 s를 문자 리스트 l로 변환합니다.
- i를 k-1로 초기화합니다. 이 값은 첫 번째 블록의 마지막 문자 인덱스입니다.
- i가 len(l) + k보다 작은 동안 아래 과정을 반복합니다.
- a := l[0 : i-k+1] → 현재 블록 앞부분
- b := l[i-k+1 : i+1] → 뒤집을 대상 블록
- c := l[i+1 :] → 현재 블록 뒷부분
- l := a + b(역순) + c 형태로 리스트를 재조립합니다.
- i를 2k만큼 증가시켜 다음 블록으로 이동합니다.
- 리스트의 모든 문자를 이어 붙여 문자열로 반환합니다.
구현 예제
아래 코드를 통해 실제 동작을 확인해 보겠습니다.
class Solution:
def reverseStr(self, s, k):
l = list(s)
i = k - 1
while i < len(l) + k:
a = l[:i-k+1]
b = l[i-k+1:i+1]
c = l[i+1:]
l = a + b[::-1] + c
i += 2 * k
return ''.join(l)
ob = Solution()
print(ob.reverseStr("abcdefg", 3))실행 결과
입력: "abcdefg", k = 3
출력: cbadefg
첫 3글자 "abc"가 "cba"로 뒤집히고, 다음 3글자 "def"는 규칙에 따라 그대로 유지됩니다. 마지막 한 글자 "g"는 한 글자를 뒤집어도 변화가 없으므로 결과적으로 "cbadefg"가 출력됩니다.
더 간결한 대안 코드
파이썬의 슬라이싱과 range를 활용하면 같은 로직을 훨씬 짧게 표현할 수 있습니다.
class Solution:
def reverseStr(self, s, k):
s = list(s)
for i in range(0, len(s), 2 * k):
s[i:i+k] = s[i:i+k][::-1]
return ''.join(s)이 방식은 2k 간격으로 시작 인덱스를 순회하며 각 위치에서 최대 k개의 문자만 뒤집습니다. 남은 문자가 k개 미만일 때도 슬라이싱이 자동으로 유효 범위 안에서만 동작하기 때문에 별도의 조건 분기가 필요하지 않습니다. 시간 복잡도와 공간 복잡도는 모두 O(n)입니다.