[ JS 코딩테스트 LV 2] 괄호 회전하기

SeungJin·2022년 9월 28일
0

JS코딩테스트

목록 보기
63/111

문제 설명

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

  • (), [], {} 는 모두 올바른 괄호 문자열입니다.
  • 만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다.
  • 만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다.
  • 대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요.

제한사항

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

입출력 예

sresult
"{}"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"}]()[{"X
1"]()[{}"X
2"()[{}]"O
3")[{}]("X
4"{}"O
5"{}]()["X

올바른 괄호 문자열이 되는 x가 2개이므로, 2를 return 해야 합니다.
입출력 예 #3

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

입출력 예 #4

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

풀이

const solution = (s) => {
    // 올바른 괄호를 카운터
    let answer = 0;
    // 문자열 s를 문자 배열로 변환
    s = s.split('');
    // 올바른 문자열은 괄호, 중괄호, 대괄호 한쌍씩 있어야 하므로 문자열의 길이가
    // 절대 홀수가 나올수 없음
    if (s.length === 1 || s.length % 2 !== 0) return 0;
    // 배열의 길이만큼 반복;
    for (let a = 0; a < s.length; a++) {
      // 배열 s의 0번째 원소가 '(', '{', '['로 시작하면 문자 배열을 체크해주는
      // 함수 실행후 실행 결과값을 더해줍니다.
      if (s[0] === '(' || s[0] === '{' || s[0] === '[') {
        answer += check(s);
      }
      // 조건문을 지나면 배열의 첫번째 요소를 뒤로 이동
      s.push(...s.splice(0, 1));
    }
    return answer;
  };



  // 호이스팅 되는 문자를 체크해 주는 함수
  function check(s) {
    // 배열의 요소를 순서대로 담을 배열 선언
    let arr = [];
    // 배열 s의 길이만큼 반복
    for (let b = 0; b <= s.length; b++) {
      // s[b]의 요소가 '(', '{', '['일 경우 arr에 Push
      switch (s[b]) {
        case '(':
          arr.push(s[b]);
          break;
        case '{':
          arr.push(s[b]);
          break;
        case '[':
          arr.push(s[b]);
          break;
        // s[b]의 요소가 ')', '}', ']'일 경우 현제 arr의 마지막 요소가
        // 해당 괄호의 여는 괄호 인지 확인
        case ')':
          // 마지막 요소가 해당 괄호의 여는 괄호가 아니라면 0을 리턴
          if (arr[arr.length - 1] !== '(') {
            return 0;
          }
          // 조건문을 통과하면 마지막 요소 삭제
          arr.pop();
          break;
        case '}':
          if (arr[arr.length - 1] !== '{') {
            return 0;
          }
          arr.pop();
          break;
        case ']':
          if (arr[arr.length - 1] !== '[') {
            return 0;
          }
          arr.pop();
          break;
      }
    }
    // 올바른 괄호일경우 반복문이 끝나는 시점에 arr의 길이는 0이 되어야 합니다.
    // arr의 길이가 0일경우 1 아니라면 0을 리턴
    return arr.length === 0 ? 1 : 0;
  }

추가설명

문제를 풀다가 계속 틀리던 부분이 괄호들의 개수에만 신경을 써서 순서를 놓쳐 한참을 해맸습니다( 테스트 케이스 14 ), s([{)}]일경우
제가작성한 풀이의 로직대로 순서대로 보면
1. arr.push(s[b]) -> arr[ '(' ]
2. arr.push(s[b]) -> arr[ '(', '[' ]
3. arr.push(s[b]) -> arr[ '(', '[', '{' ]
4. s[b]')' 이라면 arr의 마지막 요소가 '(' 되야 하지만
현제 arr -> arr[ '(', '[', '{' ] 이므로 스택(후입 선출)이 정상적으로 이뤄지지 않아서 올바른 문자열이 아닙니다.

profile
혼자 공부해 보고 적어두는 블로그입니다 문제 있다고 생각되시는 부분이 있으면 피드백이라도 남겨주시면 감사하겠습니다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN