상근이는 문자열에 폭발 문자열을 심어 놓았다. 폭발 문자열이 폭발하면 그 문자는 문자열에서 사라지며, 남은 문자열은 합쳐지게 된다.
폭발은 다음과 같은 과정으로 진행된다.
상근이는 모든 폭발이 끝난 후에 어떤 문자열이 남는지 구해보려고 한다. 남아있는 문자가 없는 경우가 있다. 이때는 "FRULA"를 출력한다.
폭발 문자열은 같은 문자를 두 개 이상 포함하지 않는다.
첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다.
둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다.
두 문자열은 모두 알파벳 소문자와 대문자, 숫자 0, 1, ..., 9로만 이루어져 있다.
첫째 줄에 모든 폭발이 끝난 후 남은 문자열을 출력한다.
처음에는 split과 join을 활용해서 해결할 수 있을 것 같았다.
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)
split과 join을 여전히 사용하고 있어서 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 대신 스택을 활용하여 한 번의 순회만 수행split과 join의 시간 복잡도 문제split(bomb)을 사용할 경우, 최악의 경우 O(N)join()을 사용하면 문자열을 새로 생성해야 하므로 O(N)| 접근 방식 | 시간 복잡도 | 문제점 |
|---|---|---|
split + join 반복 | O(N^2) | 문자열을 반복적으로 쪼개고 합쳐서 시간 초과 발생 |
| 스택 활용 (비효율적) | O(N^2) | split과 join을 여전히 사용하여 비효율적 |
| 스택 활용 (최적화) | O(N) | 한 번의 순회로 해결 가능 |
split과 join을 사용하면 시간 초과가 발생할 가능성이 크다.