[프로그래머스] 스택/큐 > 쇠막대기

문제

쇠막대기와 쇠막대기를 자르는 레이저의 배치를 표현한 문자열 arrangement가 주어질 때 쇠막대기 조각의 개수를 return 하세요.

조건

  • 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있습니다.
  • 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓습니다.
  • 각 쇠막대기를 자르는 레이저는 적어도 하나 존재합니다.
  • 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않습니다.
  • 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 ’()‘으로 표현합니다. 또한 모든 ’()‘는 반드시 레이저를 표현합니다.
  • 쇠막대기의 왼쪽 끝은 여는 괄호 ’(‘로, 오른쪽 끝은 닫힌 괄호 ’)‘로 표현됩니다.
  • arrangement의 길이는 최대 100,000입니다.
  • arrangement의 여는 괄호와 닫는 괄호는 항상 쌍을 이룹니다.

방법

  • 열린 괄호가 들어오면 쇠막대기 수를 증가시킨다.
  • 닫는 괄호가 쇠막대기의 끝인지 레이저인지 구별한다.
  • 레이저일 경우 카운팅한 쇠막대기 수만큼 쇠막대기 조각수를 증가시킨다.
  • 레이저가 아닌 닫는 괄호가 들어왔을 경우 조각수를 한 개 증가시킨다.

문제풀이

def solution(arrangement: str) -> int:
    answer = 0
    pipes = 0
    is_laser = False

    for a in arrangement:
        if a == ")":
            pipes -= 1 # 레이저인 경우에도 pipes의 값을 증가시켰기 때문에 항상 1을 빼준다.
            if is_laser: # 레이저인 경우
                answer += pipes # 이번 레이저로 생긴 조각수 추가
                is_laser = False  # 다시 닫는 괄호가 들어왔을 때는 레이저가 아님
            else: # 쇠막대기의 끝
                answer += 1
        else: # 새로운 쇠막대기 또는 레이저
            pipes += 1
            is_laser = True # 다음 닫는 괄호는 레이저임
    return answer

처음에는 스택을 생각하고 하다가 pipes를 배열로 만들어서 했는데 일반 스택처럼 스택안에 들어있는 데이터로 작업이 필요한 게 아니라 단순히 카운팅만을 위한 스택이기 때문에(괜히 메모리만 증가시킨다.) 정수로 변경해서 계산했다.

테스트 코드

class TestCase(unittest.TestCase):
    def test_solution(self):
        self.assertEqual(solution("()(((()())(())()))(())"), 17)
        self.assertEqual(solution("()"), 0)
        self.assertEqual(solution("(())((()()))"), 8)

어려웠던 점

  • 스택의 개념을 알고있으니 쉽게 해결할 수 있었다. 😀

Written by@EHX
Software Developer, Back-End Engineer

GitHubFacebook