[프로그래머스] 괄호 회전하기 - Java(자바)

김민철(MInCheol Kim)·2024년 8월 8일
post-thumbnail

문제

괄호 회전하기(https://school.programmers.co.kr/learn/courses/30/lessons/76502)

문제 설명

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

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

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

제한사항

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

입출력 예

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

입출력 예 #3

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

입출력 예 #4

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

풀이

문제 파악

  • stack을 이용하여 모든 괄호에 대해 쌍을 맞춰 pop시키고, stack을 모두 비울 수 있는지 여부에 따라 올바른 괄호 문자열인지 확인
  • 주어진 괄호 문자열(s)의 길이는 1 <= s <= 10310^3 이고 문자열의 회전은 s.length번 하게되므로 올바른 괄호 문자열인지 s.length번 검사하게 됨

접근 방법

  • solution 함수: 괄호 문자열 s를 왼쪽으로 한 칸씩 회전시킬 때마다 isValid 함수를 통해 유효한 괄호 문자열인지 검사하고 유효한 괄호 문자열일 경우, answer에 +1을 해줌.
    s.length번 반복하고 answer를 return
  • isValid 함수:
    1. s를 한 글자씩 순회하며 해당 글자가 열린 괄호([ "(", "{", "[" ])라면 stack에 push.
    2. 닫힌 괄호([ ")", "}", "]" ])라면, stack이 비었는지 먼저 확인
      • stack이 비어있는데 닫힌 괄호가 나왔다는 것은 유효한 괄호 문자열이 아니라는 것을 의미
    3. stack의 top에 저장된 요소가 같은 쌍의 열린 괄호인지 확인하고, 맞다면 pop
    4. 모든 문자열에 대한 검사가 끝난 후 stack이 비어있는지 여부를 반환
      • stack이 비어있다면, 모든 괄호가 쌍을 이루었다는 의미이므로 유효한 괄호 문자열이라고 판단하여 true 반환. 반대의 경우 false 반환.

코드 구현

import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;

        for (int i = 0; i < s.length(); i++) {
            if (isValid(s)) answer += 1;
            s = s.substring(1) + s.charAt(0);
        }

        return answer;
    }

    public boolean isValid(String s) {
        Deque<Character> stack = new ArrayDeque<>();

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch == '(' || ch == '[' || ch == '{') {
                stack.push(ch);
            } else {
                if (stack.isEmpty()) return false;
                if ((stack.peek() == '(' && ch == ')') ||
                    (stack.peek() == '[' && ch == ']') ||
                    (stack.peek() == '{' && ch == '}')) {
                    stack.pop();
                }
            }
        }
        return stack.isEmpty();
    }
}
profile
궁금한 건 다 해보는 개발자 지망생

0개의 댓글