(프로그래머스 76502) 괄호 회전하기

ps  · 3 mins read

이해

  • 다음 규칙을 지키는 문자열은 올바른 괄호 문자열이라고 정의한다.
    • (), [], {}는 모두 올바른 괄호 문자열이다.
    • A가 올바른 괄호 문자열이면, (A), [A], {A}도 올바른 괄호 문자열이다.
    • A, B가 올바른 괄호 문자열이면, AB도 올바른 괄호 문자열이다.
  • s가 매개변수로 주어질 때, s를 왼쪽으로 x(0 <= x < s의 길이)칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return하라.

계획

  • 완전 탐색으로 접근한다. 가능한 모든 x값에 대해서 s를 x칸 회전시킨 문자열이 올바른 괄호 문자열인지 확인한다.
  • s를 왼쪽으로 1칸 회전하는 함수를 구현한다.
  • 주어진 문자열이 올바른 괄호 문자열인지 체크해주는 함수를 구현한다.
  • 올바른 괄호 문자열인지 확인하는 방법
    • stack 자료구조를 사용해서 문자열 s에 속해있는 문자를 stack에 하나씩 푸시한다.
    • stack의 맨 위에 있는 두 개의 문자를 합친 문자열이 올바른 괄호 문자열일 경우에 두 개의 문자를 제거해 준다.
    • 문자열 s에 속해있는 모든 문자를 stack에 넣어준 후에 stack이 비어있을 경우 주어진 문자열이 올바른 괄호 문자열이 맞다.
  • 시간 복잡도는 O(N^2)이다.

실행

def one_step_left(s):
    return s[1:] + s[0]

def is_right(s):
    stack = []
    for c in s:
        stack.append(c)
        if len(stack) >= 2 and stack[-2] + stack[-1] in ['()', '[]', '{}']:
            stack.pop()
            stack.pop()
    return True if not stack else False
    
    
def solution(s):
    count = 1 if is_right(s) else 0
    
    for _ in range(len(s) - 1):
        s = one_step_left(s)
        if is_right(s):
            count += 1
    return count

개선

  • 문자열을 왼쪽으로 1칸 회전하는 방법이 매우 간단하므로 one_step_left 함수를 선언하지 않고 구현한다.
  • 0칸 회전하는 경우는 굳이 따로 for문 밖에서 처리하지 않고 s의 길이만큼 회전하는 경우로 취급해서 for문 안에서 같이 처리하면 코드가 훨씬 깔끔해진다.
def is_right(s):
    stack = []
    for c in s:
        stack.append(c)
        if len(stack) >= 2 and stack[-2] + stack[-1] in ['()', '[]', '{}']:
            stack.pop()
            stack.pop()
    return True if not stack else False
    
    
def solution(s):
    count = 0
    for _ in range(len(s)):
        s = s[1:] + s[0]
        if is_right(s):
            count += 1
    return count

회고

  • 계획을 잘 세워서 깔끔하게 잘 푼 것 같다.
  • 만족스럽다.