Level 2 ) 괄호 회전하기 ⭐️

Doozuu·2023년 7월 12일
0

프로그래머스 (JS)

목록 보기
128/183

문제 설명

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

  • (), [], {} 는 모두 올바른 괄호 문자열입니다.
  • 만약 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

입출력 예 설명

입출력 예 #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

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

입출력 예 #3

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

입출력 예 #4

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


풀이

  1. 문자열 길이만큼 회전시키기
  • shift & push하면 시간이 오래 걸리므로 문자열 길이 * 2 해서 index를 옮기기
    ex. [](){}[](){}.slice(i,i+s.length)
  1. 문자열이 올바른지 체크하기(함수로 만들어서)
  • 닫는게 먼저 나오면 무조건x
  • 여는것의 개수와 닫는것의 개수가 같아야 함.
  1. 어떻게 해도 안되면 0을 return하기

한 가지 케이스에서 틀려서 예외 케이스가 무엇이 있을지 생각해봤는데, ({)} 인 경우에 올바른 괄호로 인식을 하는 문제가 있었다.
순서는 신경쓰지 않고 갯수로만 체크를 하다보니 이런 문제가 발생했다.

function solution(s) {
    let str = s.repeat(2);
    let answer = 0;
    
    for(let i=0;i<s.length;i++){
        let rotate = str.slice(i,i+s.length);
        if(!(s.length % 2)) answer += check(rotate);
    }
    
    function check(n){
        let s = 0;
        let m = 0;
        let l = 0;
        for(let i=0;i<n.length;i++){
            let el = n[i];
            if(el === "("){
                s++;
            }else if(el === ")"){
                s--;
            }else if(el === "{"){
                m++;
            }else if(el === "}"){
                m--;
            }else if(el === "["){
                l++;
            }else if(el === "]"){
                l--;
            } 
            if(s < 0 || m < 0 || l < 0) return 0;
        }
        return s === 0 && m === 0 && l === 0 ? 1 : 0;
    }
    
    return answer;
}

스택을 이용한 풀이

  • 여는 괄호가 나올 때는 스택에 push한다.
  • 닫는 괄호가 나올 때는 스택의 마지막 요소를 꺼내서 둘이 짝이 맞을 때 continue해준다.
  • 짝이 맞지 않을 때는 올바른 괄호가 아니므로 break한다.
  • rotate시킨 문자열을 문제없이 전부 순회한 경우(isCorrect가 true일 경우) answer++한다.
function solution(s) {
    let str = s.repeat(2);
    let stack = [];
    let answer = 0;
    let isCorrect = true;
    
    if(s.length % 2) return 0; // 길이가 홀수면 회전시켜도 안된다.
    
    for(let i=0;i<s.length;i++){
        let rotate = str.slice(i,i+s.length);
        isCorrect = true;
        for(let str of rotate){
            if(str === "(" || str === "{" || str === "["){
                stack.push(str);
            }else{
                if(str === ")" && stack.pop() === "(") continue;
                if(str === "}" && stack.pop() === "{") continue;
                if(str === "]" && stack.pop() === "[") continue;
                isCorrect = false;
                break;
            }
        }
        if(isCorrect) answer++;
    }
    return answer;
}

https://velog.io/@kimjiwonpg98/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B4%84%ED%98%B8-%ED%9A%8C%EC%A0%84%ED%95%98%EA%B8%B0-javascript

profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글