문제 설명
다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 정의합니다.
(), [], {}
는 모두 올바른 괄호 문자열입니다.- 만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다.
- 만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다.
- 대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요.
제한사항
- s의 길이는 1 이상 1,000 이하입니다.
입출력 예
입출력 예 설명
입출력 예 #1
- 올바른 괄호 문자열이 되는 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
가([{)}]
일경우 제가작성한 풀이의 로직대로 순서대로 보면
arr.push(s[b])
->arr[ '(' ]
arr.push(s[b])
->arr[ '(', '[' ]
arr.push(s[b])
->arr[ '(', '[', '{' ]
s[b]
가')'
이라면 arr의 마지막 요소가'('
되야 하지만 현제arr -> arr[ '(', '[', '{' ]
이므로 스택(후입 선출)이 정상적으로 이뤄지지 않아서 올바른 문자열이 아닙니다.