문제 설명
다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 정의합니다.
- (), [], {} 는 모두 올바른 괄호 문자열입니다.
- 만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다.
- 만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다.
대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요.
- s의 길이는 1 이상 1,000 이하입니다.
1. 이전 백준에서 '괄호'문제에서 힌트를 가지고 왔다. 이걸 먼저 풀어보면 이해가 쉽다.
https://chsususua.tistory.com/82
[실버] 괄호 (9012번)_JS
문제 괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)
chsususua.tistory.com
2. s = {}[]() 라면 앞요소를 뒤로 넣는 작업을 해 5번 완전한 괄호인지 확인을 해야한다.
> 때문에 완전한 괄호인지 확인하는 함수를 만들어 각 s에 함수를 적용해보기로 했다.
> 완전한 괄호인지 확인하는 함수 = check(arr) ;
3. check()
>괄호가 총 3세트이다. 각 세트를 다른 숫자로 설정하고, 여는 괄호에 +를, 닫는 괄호에 -를 붙였다. > map 생성
괄호 | ( | ) | [ | ] | { | } |
숫자 | 1 | -1 | 2 | -2 | 3 | -3 |
> 근데 하나의 괄호처럼 그냥 +-처리해서 열리고 닫히고를 처리하면 '([)]' 같은 것은 옳은 것으로 나온다.
> 때문에 stack으로 해서 넣은 순서대로 빼내 확인을 하는 구조로 만들었다.
> 열린 괄호는 stack에 숫자로 넣고 닫힌괄호는 stack의 마지막 거랑 숫자를 더해서 0이면 둘이 상쇄되어 사라진다.
> 결과적으로 stack에 아무것도 없으면 모두 사라진 것이므로 완전한 괄호이다.
> 다만, 그러면 닫는 괄호만 연속으로 나오면 stack에 아무것도 쌓이지 않아 오류가 발생한다.
> 이를 방지하기 위해 sum을 통해 stack과 상관없이 +-를 하고, 결과적으로 이 조건까지 0이어야 완전한 괄호이다.
4. solution(s)
> 앞 요소를 빼내서 뒤로 다시 넣어준다.
> for반복문을 통해 각 배열을 check()하고 되는 경우 return 값을 +1 한다.
5. 근데 프로그래머스에서 forEach, shift가 TypeError가 뜬다ㅠㅠㅠ 이유는 알 수 없다..
> 그래서 forEach, shift를 사용한 방법, 사용하지 않은 방법 두 가지로 만들었다.
1. forEach, shift 사용
function solution(s) {
function check(arr) {
const bracket = new Map([["(", 1], [")", -1], ["[", 2], ["]", -2], ["{", 3], ["}", -3]])
const stack = [];
let sum = 0;
for (let j = 0; j < arr.length; j++) {
let x = arr[j];
let matchNum = bracket.get(x);
sum += matchNum;
if (matchNum > 0) stack.push(matchNum);
else {
if (stack[stack.length - 1] + matchNum === 0) stack.pop();
}
}
return (stack.length === 0) && (sum === 0) ? 1 : 0;
}
let val = s;
let result = 0;
for (let i = 1; i <= s.length; i++) {
result += check(val);
val = [...s.slice(i,), ...s.slice(0, i)];
}
return result;
}
2. forEach, shift 미사용
function solution(s) {
function check(arr) {
const bracket = new Map([["(", 1], [")", -1], ["[", 2], ["]", -2], ["{", 3], ["}", -3]])
const stack = [];
let sum = 0;
for (let j = 0; j < arr.length; j++) {
let x = arr[j];
let matchNum = bracket.get(x);
sum += matchNum;
if (matchNum > 0) stack.push(matchNum);
else {
if (stack[stack.length - 1] + matchNum === 0) stack.pop();
}
}
return (stack.length === 0) && (sum === 0) ? 1 : 0;
}
let val = s;
let result = 0;
for (let i = 1; i <= s.length; i++) {
result += check(val);
val = [...s.slice(i,), ...s.slice(0, i)];
}
return result;
}
'프로그래머스' 카테고리의 다른 글
[2단계] H-Index_JS (0) | 2023.02.01 |
---|---|
[2단계] 구명보트_JS (1) | 2023.01.31 |
[2단계] 예상 대진표_JS (0) | 2023.01.26 |
[2단계] 피보나치 수_JS (0) | 2023.01.26 |
[2단계] 영어 끝말잇기 (0) | 2022.11.23 |