알고리즘 풀이/백준

[백준 15926] 현욱은 괄호왕이야

mhko411 2021. 6. 15. 15:32
728x90

문제

여는 괄호 ‘(’와 닫는 괄호 ‘)’로 구성된 문자열에서 아래의 조건을 만족하는 문자열을 올바른 괄호 문자열이라고 부른다.

  1. () 는 올바른 괄호 문자열이다
  2. 어떤 문자열 x가 올바른 괄호 문자열이라면, (x)도 올바른 괄호 문자열이다.
  3. 어떤 문자열 x와 y가 올바른 괄호 문자열이라면, xy도 올바른 괄호 문자열이다.

현욱은 친구로부터 생일 선물로 굉장히 긴 괄호 문자열을 받았다(도대체 왜 이런 걸 선물하는걸까?). 하지만 현욱은 올바른 괄호 문자열이 아니면 굉장히 싫어하기 때문에, 받은 괄호 문자열에서 연속한 일부분을 잘라서 올바른 괄호 문자열을 만들려고 한다. 그리고 이왕이면 긴 문자열이 좋으니 현욱은 부분 구간을 최대한 길게 잘라내려고 한다. 현욱을 도와 주어진 괄호 문자열에서 위의 조건을 만족하는 가장 긴 부분 문자열의 길이를 계산하는 프로그램을 작성해보자.

 

입력

첫 줄에 문자열의 길이 n (1 ≤ n ≤ 200,000)이 주어진다.

둘째 줄에 괄호로만 구성된 길이 n짜리 문자열이 주어진다.

 

출력

주어진 문자열에서 길이가 가장 길면서 올바른 괄호 문자열인 부분 문자열의 길이를 출력한다. 올바른 괄호 문자열인 부분 문자열을 찾을 수 없는 경우 0을 출력한다.


접근

다른 사람의 풀이를 참고하였다.

올바른 괄호인 경우 해당 쌍을 모두 1로 표시를 하는 방법이다. 여는 괄호일 때는 스택에 인덱스를 넣어주고 닫는 괄호일 때는 현재 인덱스와 스택의 top에 있는 인덱스에 1로 표시한다. 

이후 1이 가장 길게 연속되는 부분을 해로 출력한다.

 

구현

- 괄호열을 탐색한다.

- 여는 괄호일 때는 스택에 현재 인덱스를 push한다.

- 닫는 괄호일 때는 스택이 비어있지 않을 때 현재 인덱스와 스택의 top의 인덱스에 1로 표시한다. => 이 두개가 짝이 맞는 것이다.

- 이후 스택을 pop한다.

for idx in range(N):
    if S[idx] == '(':
        stack.append(idx)
    else:
        if stack:
            counter[idx] = counter[stack[-1]] = 1
            stack.pop()

- 이제 0과 1로 표시된 counter 리스트에서 1이 가장 길게 연속된 부분을 찾도록 한다.

answer = 0
count = 0
for number in counter:
    if number == 1:
        count += 1
        answer = max(answer, count)
    else:
        count = 0

전체 코드

import sys
input = sys.stdin.readline

N = int(input())
S = input().strip()
stack = []
counter = [0] * N
for idx in range(N):
    if S[idx] == '(':
        stack.append(idx)
    else:
        if stack:
            counter[idx] = counter[stack[-1]] = 1
            stack.pop()

answer = 0
count = 0
for number in counter:
    if number == 1:
        count += 1
        answer = max(answer, count)
    else:
        count = 0
print(answer)

'알고리즘 풀이 > 백준' 카테고리의 다른 글

[백준 2580] 스도쿠  (0) 2021.06.17
[백준 2661] 좋은수열  (0) 2021.06.16
[백준 11899] 괄호 끼워넣기  (0) 2021.06.15
[백준 12789] 도키도키 간식드리미  (0) 2021.06.14
[백준 5002] 도어맨  (0) 2021.06.14