상근이는 문자열에 폭발 문자열을 심어 놓았다. 폭발 문자열이 폭발하면 그 문자는 문자열에서 사라지며, 남은 문자열은 합쳐지게 된다.
폭발은 다음과 같은 과정으로 진행된다.
문자열이 폭발 문자열을 포함하고 있는 경우에, 모든 폭발 문자열이 폭발하게 된다. 남은 문자열을 순서대로 이어 붙여 새로운 문자열을 만든다.
새로 생긴 문자열에 폭발 문자열이 포함되어 있을 수도 있다.
폭발은 폭발 문자열이 문자열에 없을 때까지 계속된다.
상근이는 모든 폭발이 끝난 후에 어떤 문자열이 남는지 구해보려고 한다. 남아있는 문자가 없는 경우가 있다. 이때는 "FRULA"를 출력한다.
폭발 문자열은 같은 문자를 두 개 이상 포함하지 않는다.
첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다.
둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다.
두 문자열은 모두 알파벳 소문자와 대문자, 숫자 0, 1, ..., 9로만 이루어져 있다.
첫째 줄에 모든 폭발이 끝난 후 남은 문자열을 출력한다.
mirkovC4nizCC44
C4
mirkovniz
12ab112ab2ab
12ab
FRULA
문제를 보면 replace를 반복하면 해결할 수 있을 것처럼 보이지만, 그렇게 호락호락한 문제가 아닐 것 같다는 생각이 듭니다.
실제로 아래와 같이 replace를 사용하면 시간 초과가 발생합니다.
import sys
input = sys.stdin.readline
str = input().strip() # 입력 문자열
explosion_str = input().strip() # 폭발 문자열
prev = '' # replace 이전의 문자열 저장
while prev != str: # replace를 더 이상 할 게 없다면 종료
prev = str
str = str.replace(explosion_str, '')
print(str if str else 'FRULA')
replace의 경우, 시간복잡도는
문자열의 길이 (교체할 문자열의 길이 + 교체되는 문자열의 길이)
입니다.
따라서 위의 코드는 최악의 경우 의 시간복잡도를 가질 수 있습니다.
따라서 이 문제는 stack의 pop을 활용하여 시간 초과 없이 해결할 수 있습니다.
import sys
input = sys.stdin.readline
str = input().strip() # 입력 문자열
explosion_str = list(s for s in input().strip()) # 폭발 문자열
stack = [] # 스택
for s in str:
stack.append(s)
if stack[-1] == explosion_str[-1] and stack[-len(explosion_str):] == explosion_str:
for _ in range(len(explosion_str)):
stack.pop()
print(''.join(stack) if len(stack) else 'FRULA')
스택을 만들어 스택에 입력받은 문자열의 문자들을 하나씩 추가합니다.
만약 추가한 문자가 폭발 문자열의 마지막 글자와 동일하다면, 스택의 마지막문자부터 폭발 문자열의 길이만큼의 앞 문자들과 같은지를 확인합니다.
만약, 동일하다면 해당 문자들은 pop 해줍니다.
모든 문자들을 스택에 추가하고, 폭발 문자열들을 모두 폭발시켰다면 스택의 문자들을 join을 통해서 출력해줍니다.
이렇게 스택을 사용하면 위의 replace 코드처럼 문자열을 여러 번 반복하여 탐색할 필요도 없고, 연산 속도 자체도 빠르기 때문에 문제를 해결할 수 있습니다.
처음에는 코드의 stack.pop()부분을 stack[-len(explostion_str):]처럼 슬라이싱을 통해서 문제를 해결하려고 했습니다.
두 연산의 시간복잡도는 아래와 같습니다.
pop : [a:b] : pop의 연산이 많다면 슬라이싱을 사용하는 것이 좀 더 시간을 줄여줄 수 있겠지만, 이 문제의 경우 pop은 한 번에 최대 35번만 이루어집니다.
반면, 슬라이싱의 경우 스택의 길이와 비슷한 시간 복잡도를 가지므로 문자열의 길이가 1,000,000이나 된다면 좀 더 많은 시간이 걸릴 수 있습니다.