본문 바로가기
Coding Test

231221 괄호 회전하기 - Level 2

by mmm- 2023. 12. 21.

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

 

프로그래머스

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

programmers.co.kr

 

문제 설명

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

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

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

 

제한사항

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

 

입출력 예

 

입출력 예 설명

입출력 예 #1

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

  • 올바른 괄호 문자열이 되는 x가 3개이므로, 3을 return 해야 합니다.
  • 입출력 예 #2
  • 다음 표는 "}]()[{" 를 회전시킨 모습을 나타낸 것입니다.

  • 올바른 괄호 문자열이 되는 x가 2개이므로, 2를 return 해야 합니다.
  • 입출력 예 #3
  • s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다.
  • 입출력 예 #4
  • s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다.

 


코드

import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;
        Stack<String> stack = new Stack<>();
        Map<String, String> map = new HashMap<>();
        int count = 0;
        String sTemp = s;
        
        map.put("{", "}");
        map.put("[", "]");
        map.put("(", ")");
        
        while(count++ != s.length()) {
            for(int i=0; i<s.length(); i++) {
                if(stack.isEmpty()) {
                    stack.push(String.valueOf(s.charAt(i)));
                } else {
                    String top = stack.peek();
                    
                   if(String.valueOf(s.charAt(i)).equals(map.get(top)))
                        stack.pop();
                   else
                        stack.push(String.valueOf(s.charAt(i)));
                }
            }
            if(stack.isEmpty())
                answer++;
            
            sTemp = s;
            s = "";
            for(int i=1; i<sTemp.length(); i++) {
                s += String.valueOf(sTemp.charAt(i));
            }
            s += String.valueOf(sTemp.charAt(0));
            
            stack.clear();
        }

        return answer;
    }
}

 

풀이

올바른 괄호를 판별하기 위해 짝에 맞춰 map에 넣어준다. 그 후, s를 왼쪽으로 회전시켜 그 값이 처음의 s값과 같이질 때까지 반복한다. s의 길이만큼 for문을 돌아 문자열 s가 올바른 괄호 문자열인지 확인한다. stack이 비어있는 경우 무조건 s의 i번째 문자를 넣어주고, 그렇지 않은 경우에는 스택의 맨 위에 있는 값과 짝인 괄호와 s의 i번째 문자가 같은지 확인하여 만약 같다면 맨 위에 있는 문자를 스택에서 제거해주고, 그렇지 않다면 그냥 s의 i번째 문자를 스택에 넣어준다. 반복문을 탈출했을 때 스택이 비어있다면 올바른 괄호 문자열이라는 의미이므로 answer를 1만큼 증가시켜준다.

그리고 문자열은 왼쪽으로 회전시키기 위해 sTemp문자열에 기존의 s문자열을 넣어주고, s문자열은 빈 문자열로 만들어준다. 1부터 sTemp의 길이 전까지 반복문을 돌려 sTemp에 있는 i번째 값들을 s에 넣어주고, 반복문을 탈출하면 s에 sTemp의 0번째 값을 s문자열 마지막에 넣어준다. 그리고 새로 만들어진 문자열 s에 대해 또 확인을 하는데 이 때, 스택이 채워져 있을 경우 제대로 확인이 불가능하기 때문에 stack.clear()을 하여 스택을 모두 비워준다.