[백준] 9935번 - 문자열 폭발

ungnam·2025년 3월 21일

문제 설명

상근이는 문자열에 폭발 문자열을 심어 놓았다. 폭발 문자열이 폭발하면 그 문자는 문자열에서 사라지며, 남은 문자열은 합쳐지게 된다.

폭발은 다음과 같은 과정으로 진행된다.

  • 문자열이 폭발 문자열을 포함하고 있는 경우에, 모든 폭발 문자열이 폭발하게 된다. 남은 문자열을 순서대로 이어 붙여 새로운 문자열을 만든다.
  • 새로 생긴 문자열에 폭발 문자열이 포함되어 있을 수도 있다.
  • 폭발은 폭발 문자열이 문자열에 없을 때까지 계속된다.

상근이는 모든 폭발이 끝난 후에 어떤 문자열이 남는지 구해보려고 한다. 남아있는 문자가 없는 경우가 있다. 이때는 "FRULA"를 출력한다.

폭발 문자열은 같은 문자를 두 개 이상 포함하지 않는다.

입력

첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다.

둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다.

두 문자열은 모두 알파벳 소문자와 대문자, 숫자 0, 1, ..., 9로만 이루어져 있다.

출력

첫째 줄에 모든 폭발이 끝난 후 남은 문자열을 출력한다.


초기 접근 방법

처음에는 splitjoin을 활용해서 해결할 수 있을 것 같았다.

s = input()
bomb = input()

while True:
    t = ''.join(s.split(bomb))
    if s == t or t == '':
        s = t
        break
    s = t

print('FRULA' if s == '' else s)

❌ 문제점

이 코드는 split을 이용해 폭발 문자열을 제거하고, join을 통해 다시 문자열을 합치는 방식을 반복한다. 하지만 문자열을 계속 쪼개고 합치는 과정에서 시간 복잡도가 O(N^2) 이상 증가하여 46%에서 시간 초과가 발생했다.

스택을 활용한 접근

이중 반복문을 줄이기 위해 스택을 활용하는 방식으로 변경했다.

s = input()
bomb = input()

stk = s.split(bomb)
t = ''
while stk:
    t = stk.pop() + t
    tt = ''.join(t.split(bomb))
    if t == tt:
        continue
    stk.append(tt)
    t = ''

print('FRULA' if t == '' else t)

❌ 여전히 문제 발생

  • splitjoin을 여전히 사용하고 있어서 1%에서 시간 초과가 발생했다.
  • 문자열을 계속 변환하는 과정에서 성능이 떨어진다.

최적화된 스택 방식 적용

힌트를 참고해보니, 문자열 하나씩 추가하면서 폭발 문자열이 만들어지면 제거하는 방식이 효율적이라고 했다. 이를 반영하여 코드를 다음과 같이 작성했다.

s = input()
bomb = input()

stk = []

for c in s:
    stk.append(c)
    if len(stk) >= len(bomb) and stk[-len(bomb):] == list(bomb):
        for _ in range(len(bomb)):
            stk.pop()

print(''.join(stk) if stk else 'FRULA')

✅ 개선된 점

  • 문자열을 자르고 합치는 연산 제거split, join 대신 스택을 활용하여 한 번의 순회만 수행
  • O(N)으로 해결 가능 → 매번 폭발 문자열이 등장하면 바로 삭제하는 구조

6. splitjoin의 시간 복잡도 문제

  • split(bomb)을 사용할 경우, 최악의 경우 O(N)
  • join()을 사용하면 문자열을 새로 생성해야 하므로 O(N)
  • 이를 반복하면 최악의 경우 O(N^2) 이상 발생

8. 시간 복잡도 비교

접근 방식시간 복잡도문제점
split + join 반복O(N^2)문자열을 반복적으로 쪼개고 합쳐서 시간 초과 발생
스택 활용 (비효율적)O(N^2)splitjoin을 여전히 사용하여 비효율적
스택 활용 (최적화)O(N)한 번의 순회로 해결 가능

9. 핵심 정리 ✨

  • splitjoin을 사용하면 시간 초과가 발생할 가능성이 크다.
  • 스택을 활용하면 한 번의 순회로 해결할 수 있다.
  • O(N)으로 해결할 수 있도록 고민하는 것이 중요! 🚀
profile
꾸준함을 잃지 말자.

0개의 댓글