새소식

PS/백준

[백준/15926] 현욱은 괄호왕이야!! (Python)

  • -

Problem : https://www.acmicpc.net/problem/15926

 

15926번: 현욱은 괄호왕이야!!

첫 번째 입출력에서, 맨 처음 위치부터 4개를 잘라낸 (())가 가장 긴 올바른 괄호 문자열이다. 두 번째 입출력에서, 6번째 위치부터 8개를 잘라낸 ()((()))가 가장 긴 올바른 괄호 문자열이다.

www.acmicpc.net

 

Difficulty : Gold 3

 

Status : Solved

 

Time : ??:??:??

 


 

문제 설명

 

더보기

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

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

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

 

입력 및 출력

 

더보기

입력

 

첫 줄에 문자열의 길이 n (1 ≤ n ≤ 200,000)이 주어진다.
둘째 줄에 괄호로만 구성된 길이 n짜리 문자열이 주어진다.

 

출력

 

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

 

입력 예시

 

5
(())(

 

출력 예시

 

4

 

 


 

풀이

 

이중 스택을 사용해보자.

 

우선 괄호를 보관하는 스택을 떠올려보자. 이 스택은 '('가 들어오면 인덱스를 저장하고, ')'가 들어왔을 때 스택에 인덱스가 존재한다면 스택을 pop한다. 이렇게 만들어진 괄호 순서쌍은 [start, end]의 인덱스 범위를 포함하며, 길이는 start + end - 1이다.

 

두 번째로, 정답 후보군 스택을 생각해보자.

  • 앞서 괄호를 보관하는 스택에서 pop된 괄호 순서쌍의 start가 정답 후보군 스택의 top의 start보다 작다면, 현재 괄호 순서쌍이 정답 후보군 스택의 top을 포함함을 의미한다. 이를테면, '(())'의 경우 정답 후보군 스택에는 [1, 2]값이 들어있을 것이고, 괄호 순서쌍 [0, 3]값이 들어오게 될 것이다. 즉 두 start를 비교하여 스택의 top을 포함하는 경우를 모두 제거한다.
  • 두번째로, 괄호 순서쌍의 start가 정답 후보근 스택의 top의 end와 1차이라면, 두 괄호 순서쌍은 이어질 수 있다. 이를테면 '()()'의 경우, 정답 후보군 스택에는 [0, 1]이, 괄호 순서쌍은 [2, 3]값이 들어올 것이다. 이 경우는 두 범위를 합쳐 새로 정답 후보군 스택에 삽입한다.

최종적으로 정답 후보군 스택에는 올바른 괄호 문자열의 가장 큰 부분집합들이 포함되어 있으며, 이들 중 제일 길이가 긴 괄호 순서쌍의 길이를 출력하면 된다.

 

풀이 코드

N = int(input())
string = input().strip()
stack = []
answers = [[-1, -2]]
for i in range(N) :
  if string[i] == '(' :
    stack.append(i)
  elif stack :
    tmp = [stack.pop(), i]
    while answers and answers[-1][0] > tmp[0] :
      answers.pop()
    if answers and answers[-1][1] + 1 == tmp[0] :
      tmp[0] = answers.pop()[0]
    answers.append(tmp)

answers.sort(key = lambda x : x[1] - x[0])
print(answers[-1][1]-answers[-1][0]+1)

풀이 완료!

'PS > 백준' 카테고리의 다른 글

[백준/28018] 시간이 겹칠까?  (0) 2024.05.09
[백준/13023] ABCDE  (0) 2024.05.08
[백준/1285] 동전 뒤집기 (Python)  (1) 2024.03.22
[백준/4243] 보안 업체 (Python)  (0) 2024.03.21
[백준/30014] 준영이의 사랑 (Python)  (0) 2024.03.20
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.