코딩 테스트(Coding Test)/프로그래머스

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

잇트루 2023. 8. 28. 00:48
반응형

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/76502

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제 설명

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

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

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

 

 

제한사항

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

 

 

입출력 예

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

 

 

입출력 예 설명

입출력 예 #1

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

x s를 왼쪽으로 x칸만큼 회전 올바른 괄호 문자열?
0 "[](){}" O
1 "](){}[" X
2 "(){}[]" O
3 "){}[](" X
4 "{}[]()" O
5 "}[](){" X

바른 괄호 문자열이 되는 x가 3개이므로, 3을 return 해야 합니다.

 

입출력 예 #2

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

x s를 왼쪽으로 x칸만큼 회전 올바른 괄호 문자열?
0 "}]()[{" X
1 "]()[{}" X
2 "()[{}]" O
3 ")[{}](" X
4 "[{}]()" O
5 "{}]()[" X

 

입출력 예 #3

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

 

입출력 예 #4

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

 

 

코드

import java.util.Stack;

class Solution {
    public int solution(String s) {
        // 올바른 괄호 문자열의 개수를 저장할 변수
        int answer = 0;

        for (int i = 0; i < s.length(); i++) {
            // 주어진 문자열이 올바른 괄호 문자열인지 검사
            if (verification(s)) {
                answer++;
            }

            // 문자열을 한 칸씩 회전
            s = shift(s);
        }

        return answer;
    }

    // 올바른 괄호인지 검사하는 함수
    private boolean verification(String s) {
        // 괄호를 저장할 스택
        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            // 여는 괄호면 스택에 push
            if (s.charAt(i) == '(' || s.charAt(i) == '{' || s.charAt(i) == '[') {
                stack.push(s.charAt(i));
            } else {
                // 스택이 비어있는 경우
                if (stack.isEmpty()) {
                    return false;
                }

                // 짝이 맞는 괄호면 스택에서 pop
                if (stack.peek() == '(' && s.charAt(i) == ')')  {
                    stack.pop();
                } else if (stack.peek() == '{' && s.charAt(i) == '}') {
                    stack.pop();
                } else if (stack.peek() == '[' && s.charAt(i) == ']') {
                    stack.pop();
                // 짝이 맞지 않는 경우 false
                } else return false;
            }
        }

        return stack.isEmpty();
    }

    // 문자열 회전(부분문자열 활용)
    private String shift(String s) {
        return s.substring(1) + s.charAt(0);
    }
}

코드 설명

주석 참고

  • 이 문제는 주어진 괄호 문자열을 길이만큼 한 칸씩 회전시키면서 회전시킨 문자열이 올바른 괄호로 구성된 개수를 반환하는 문제다.
  • 문자열 s의 길이만큼 반복하여 직접 구현한 verification 메서드를 통해 올바른 괄호인지 체크한다.
  • 올바른 문자열일 경우 answer를 증가시키고 아니면 넘어가고 직접 구현한 shift 함수를 통해 문자열을 한 칸씩 회전시킨다.

 

verification 메서드

  • 올바른 괄호인지 판단하기 위한 메서드로 괄호 문자열 s를 입력받아 s가 올바른 괄호인지에 따라 true 또는 false를 반환한다.
  • Character 타입의 Stack을 선언하고 for 문을 통해 s의 길이만큼 반복한다.
  • 만약 s의 i 번째 문자가 여는 괄호('(', '{', '[')인 경우 선언한 stack에 push한다.
  • 여는 괄호가 아닌 경우 스택이 비어있는지 확인하여 비어있을 경우 false를 반환한다.
  • 스택이 비어있지 않는 경우 스택의 최상단에 저장된 문자가 짝이 맞는 괄호인지 판단한다.
  • 짝이 맞는 경우 stack에서 꺼내고, 다른 경우 false를 반환한다.

 

shift 메서드

  • 괄호 문자열을 회전시키기 위한 메서드로 괄호 문자열 s를 입력받아 문자열 s의 첫 번째 문자를 맨 뒤로 옮긴 후 수정된 문자열 s를 반환한다.
  • substring() 메서드를 활용하여 첫 번째 문자를 뺀 나머지 부분문자열 뒤에 첫 번째 문자를 붙인 후 반환한다.
반응형