프로그래머스/Lv. 2

[프로그래머스 코딩테스트] 괄호 회전하기(Java)

Sigfriede 2023. 7. 10. 01:00

  문제 설명

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

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

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

 

  제한사항

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

 

  입출력 예

s result
"[](){}" 3
"}]()[{" 2
"[)(]" 0
"}}}" 0
import java.util.Stack;

class Solution {
    public int solution(String s) {
        int answer = 0;
        for (int i = 0; i < s.length(); i++) {
            String rotatedString = rotateString(s, i);
            if (isValid(rotatedString)) {
                answer++;
            }
        }
        return answer;
    }
    
    private String rotateString(String s, int rotateCount) {
        int length = s.length();
        rotateCount = rotateCount % length;
        return s.substring(rotateCount) + s.substring(0, rotateCount);
    }
    
    private boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '[' || c == '{') {
                stack.push(c);
            } else {
                if (stack.isEmpty()) {
                    return false;
                }
                char top = stack.pop();
                if ((c == ')' && top != '(') || 
                (c == ']' && top != '[') || 
                (c == '}' && top != '{')) {
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }
}

  매개 변수로 문자열 s와 정수형 rotateCount를 받는 rotateString 메소드를 생성합니다.  정수형 length에 s의 길이를 할당합니다.  rotateCount에 rotateCount를 length로 나눈 나머지를 할당합니다. rotateCount가 s의 길이보다 커지는 것을 방지하기 위함입니다.  substring 매소드를 이용하여 문자열 s를 rotateCount 번째부터 문자열의 끝까지 자른 값과 0번부터 rotateCount 번째 문자열까지 자른 값을 더한 값을 반환합니다. 이는 문자열을 회전시킨 값을 반환하기 위함입니다.  매개 변수로 문자열 s를 받는 isValid 메소드를 생성합니다.  문자를 제네릭 타입으로 갖는 Stack을 생성합니다.  for-each문에서 toCharArray 메소드를 이용하여 문자열 s를 문자 배열로 변환합니다. 문자 c는 이를 하나씩 받습니다.  if문에서 c가 '(' 또는 '[' 또는 '{'처럼 여는 괄호와 같다면 이를 push 메소드를 이용하여 stack에 삽입합니다.  앞선 조건에 해당하지 않는다면 isEmpty 메소드를 이용하여 stack이 비어있는지 확인합니다. 닫는 괄호부터 시작한다는 뜻므로 올바르지 않은 괄호 문자열이라는 뜻입니다. false를 반환합니다.  pop 메소드를 이용하여 스택의 맨윗부분을 제거합니다.  if문에서 c가 ')' 이면서 동시에 '('는 아니고, c가 ']' 이면서 동시에 '['는 아니고, c가 '}' 이면서 동시에 '{'는 아니어야 합니다. 앞서 괄호가 이미 열려있기 때문에 짝을 맞추고자 한다면, 연이어 오는 문자는 앞서 등장한 괄호와 짝인 괄호이면서 동시에 닫는 괄호여야 올바른 괄호 문자열이 되는 것입니다. 조건에 해당하지 않는다면 마찬가지로 false를 반환합니다.  매개 변수로 문자열 s를 받는 solution 함수를 생성합니다.  for문이 s의 길이만큼 순회합니다.  문자열 rotatedString은 rotateString을 호출하여 인자에 s와 i를 넣습니다.  if문에서 isValid 메소드를 호출하여 인자로 rotatedString을 넣습니다. 조건이 참이면, 즉 문제의 조건에 부합한다면 answer가 1씩 증가합니다.