Coding test

[프로그래머스] 괄호 회전하기 (Lv 2) - javascript

Jiwoo 2022. 5. 25. 18:04

문제

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


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

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

제한사항

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

 

🔑 풀이

1차 풀이

function solution(s) {

    let obj = {
        ')' : '(',
        ']' : '[',
        '}' : '{'
    };

    let answer = 0;
    s = s.split('');

    function check(s) {

        let stack = [];

        s.forEach(v => {

            if(obj[v] === stack[stack.length - 1]) stack.pop(); // 오류
            else stack.push(v); 
        });

        if(stack.length) return false;
        return true;
    };

    for (let i = 0; i < s.legnth; i++) {

        if(check(s)) answer ++;
        s.push(s.shift());
    }

    return answer;
}

 
표시한 부분에서 오류가 나서 통과하지 못하고 답이 0만 나왔다.
obj[v]이 존재하지 않을 경우의 처리를 따로 해주지 않아서다.
 

2차 풀이

function solution(s) {

    let obj = {
        ')' : '(',
        ']' : '[',
        '}' : '{'
    };

    let answer = 0;
    s = s.split('');

    function check(s) {

        let stack = [];

        for(let i = 0; i < s.length; i++) {

            let v = s[i];

            if(obj[v] === undefined) stack.push(v); // 객체에 값이 없음 (v = 여는 괄호) -> 스택에 추가

            else { // 값이 있음 (v = 닫는 괄호)
                if(obj[v] === stack[stack.length -1]) stack.pop(); // 괄호의 짝을 제대로 만남 -> 스택에서 값 빼주기
                else return false; // * 닫는 괄호가 없어지지 않고 쌓이면 무조건 실패
            }
        }

        if(stack.length) return false;
        return true;
    };

    for (let i = 0; i < s.length; i++) {

        if(check(s)) answer ++;
        s.push(s.shift());
    }

    return answer;
}

 

값이 존재하지 않을 경우의 처리를 먼저 해주고, 값이 있을 경우를 다시 처리해준다.
저기서 * 표시한 부분은 [}같이 다른 여는 괄호와 만났을 경우이다.
닫는 괄호는 들어가는 즉시 사라져야 올바른 괄호가 되므로, 해당 경우는 무조건 false이다.
이를 생각하지 못하고 v를 스택에 넣어줘도 코드가 통과된다.
하지만 시간이 훨씬 오래 걸린다.
 

  • 유의사항
    중간에 멈춰야 하는 반복문의 경우 forEach를 사용할 수 없다.
    forEach는 undefined를 반환하므로 return, break 등으로 멈추지 않는다.
     
  • 정확도 테스트 결과


     


참고

https://www.cckn.dev//