본문 바로가기

알고리즘 공부

[프로그래머스] 괄호 회전하기 - 파이썬(Python)

문제 설명

 

 

다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 정의합니다.

#1. (), [], {} 는 모두 올바른 괄호 문자열입니다.
#2. 만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다.
#3. 만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다.

대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요.

 

 


 

제한사항

 

 

  • s의 길이는 1 이상 1,000 이하입니다.

 

 


 

입출력 예

 

 

* 표의 s에서 괄호 간 띄어쓰기는 가독성을 위한 것일 뿐, 실제로는 괄호끼리 모두 붙어있습니다.

 

 

s result
" [ ] ( ) { } " 3
" } ] ( ) [ { " 2
" [ ) ( ] " 0
" } } } " 0

 

 

입출력 예 #1

  • 다음 표는 "[](){}" 를 회전시킨 모습을 나타낸 것입니다.

xs를 왼쪽으로 x칸만큼 회전올바른 괄호 문자열?

0 "[](){}" O
1 "](){}[" X
2 "(){}[]" O
3 "){}[](" X
4 "{}[]()" O
5 "}[](){" X
  • 올바른 괄호 문자열이 되는 x가 3개이므로, 3을 return 해야 합니다.

 

 

입출력 예 #2

  • 다음 표는 "}]()[{" 를 회전시킨 모습을 나타낸 것입니다.

xs를 왼쪽으로 x칸만큼 회전올바른 괄호 문자열?

0 "}]()[{" X
1 "]()[{}" X
2 "()[{}]" O
3 ")[{}](" X
4 "[{}]()" O
5 "{}]()[" X
  • 올바른 괄호 문자열이 되는 x가 2개이므로, 2를 return 해야 합니다.

 

 

입출력 예 #3

  • s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다.

 

 

입출력 예 #4

  • s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다.

 

 


 

코드 설명

 

 

deque와 Stack을 이용하여 풀이해보겠습니다.

 

먼저 주어진 문자열(괄호들) s를 deque 형태로 저장했습니다.

 

다음 이중 반복문에서 Q의 첫번째 원소를 잘라( popleft() ) 마지막 원소 뒤에 붙임으로써 괄호 회전을 실시하고, Stack을 하나 만들어줍니다.

 

이제 회전시킨 괄호가 "올바른 괄호 문자열"인지 확인해보겠습니다. Q의 어떤 글자 하나를 Q[j]라 해보죠. 우선 Stack이 비어있다면 Q[j]를 바로 Stack에 추가시킵니다. 반면 Stack에 원소가 존재한다면 Stack의 마지막 원소와 현재 글자인 Q[j]를 비교해야 합니다. 만약 Stack[-1]과 Q[j]가 서로 열고 닫는 괄호라면 pop()을 통해 Stack의 마지막 원소를 제거하고, 그렇지 않다면 Q[j]를 Stack에 추가시킵니다.

 

예를 들어 s가 " ] ( ) { } [ " 라면, Stack에는 아래와 같이 괄호가 담깁니다.

 

 

j = 0  :  Stack = [ "]" ]
j = 1  :  Stack = [ "]", "(" ]
j = 2  :  Stack = [ "]" ]
j = 3  :  Stack = [ "]", "{" ]
j = 4  :  Stack = [ "]" ]
j = 5  :  Stack = [ "]", "[" ]

 

 

반복문이 종료되었을 때 Stack이 비어있지 않으므로 s는 올바른 괄호 문자열이 아니겠네요. 반면 반복문이 종료되었을 때 Stack이 비어있다면 s는 올바른 괄호 문자열로, answer을 1 증가시키면 되겠습니다.

 

 

from collections import deque
def solution(s):
    answer = 0
    Q = deque(s)
    
    for i in range(len(s)) :
        Q.append(Q.popleft())
        Stack = []
        for j in range(len(Q)) :
            if len(Stack) < 1 :
                Stack.append(Q[j])
            else :
                if Stack[-1] == "[" and Q[j] == "]" :
                    Stack.pop()
                elif Stack[-1] == "{" and Q[j] == "}" :
                    Stack.pop()
                elif Stack[-1] == "(" and Q[j] == ")" :
                    Stack.pop()
                else : 
                    Stack.append(Q[j])
                                 
        if len(Stack) == 0 :
            answer += 1
        
    return answer