https://school.programmers.co.kr/learn/courses/30/lessons/76502#
나의 풀이
function solution(s) {
let array = s.slice()
let result = 0
for(i=0; i<s.length; i++){
while( array.length > 0){
if(array.includes("{}")) array = array.replace(/{}/g, "")
if(array.includes("[]")) array = array.replace(/\[]/g, "")
if(array.includes("()")) array = array.replace(/\(\)/g, "")
if(!array.includes("()") && !array.includes("[]") && !array.includes("{}")) break
}
if(array.length === 0 ) result++
let save = s[0]
s = s.slice(1)
s += save
array = s
}
return result
}
() 또는 {} 또는 ()가 있을 때 빈 문자열로 바꿔주는 것을 무한반복한다.
단 3개다 없을 시 while문은 종료가 된다.
그리고 문자열의 길이가 0이면 카운트를 센다.
따라서 최종적으로 왼쪽으로 s의 길이 만큼 회전시킨뒤 그 카운트를 return한다.
while 바로위에 } ] ) 로 시작하거나 { [ (로 끝나면 바로 continue시켜주면 좋다.
단 회전시키는 것도 같이해야되서 코드가 더 길어지기때문에 여기서는 하지 않았다
만약 효율성 테스트도 있다면 하는것을 무조건 추천한다.
또한 홀수 짝수도 구분해주는 것도 좋은 방법이다.
이 문제를 보고 스택으로 해야겠다고 바로 생각나지 않았다.
이전 비슷한 유형문제푼게 기억났다.
https://html-jc.tistory.com/424
이 문제는 소괄호로만 해서
function solution(s){
let sum = 0;
for(i=0; i<s.length; i++){
if(sum < 0)return false;
if(s[i] === "(") sum++;
else sum--;
}
return sum ? false : true;
}
이렇게만 하면 답이나왔다. 즉 여기는 소괄호에다가 회전하는 것도 없으니 이렇게 하면된다.
여기서는 처음에 ) 이게나오면 -1이되기때문에 바로 false가 return이 되기때문에 예외처리가 다 되었다.
하지만 이 문제는 다르다.
이 문제는 소괄호, 중괄호, 대괄호 이렇게 3개가 필요하다.
스택이 더 늘었다. 구분을 해줘야한다.
function solution(s) {
let result = 0;
for (i = 0; i < s.length; i++) {
let sum = 0;
for (item of s) {
if (s[0] === "}" || s[0] === ")" || s[0] === "]") {
sum = -1;
}
if (sum < 0) break;
if (item === "{" || item === "(" || item === "[") sum++;
else sum--;
}
let save = s[0];
s = s.slice(1);
s += save;
if (sum === 0) result++;
}
return result;
}
처음에는 이렇게 해줬다.
이렇게하면 문제점이
"(]{)" 이것도 정답이된다.
구분을 꼭 해줘야한다.
그래서 이번에는 구분을 해줬다.
function solution(s) {
let result = 0;
let distinction;
for (i = 0; i < s.length; i++) {
let sum;
let big;
let middle;
let small;
for (item of s) {
if (s.at(-1) === "{" || s.at(-1) === "[" || s.at(-1) === "(") sum = -1;
if (s[0] === "}" || s[0] === ")" || s[0] === "]") {
sum = -1;
}
if (sum < 0) break;
if (item === "{") big === undefined ? (big = 1) : big++;
else if (item === "[") middle === undefined ? (middle = 1) : middle++;
else if (item === "(") small === undefined ? (small = 1) : small++;
else if (item === "}") big === undefined ? (sum = -1) : big--;
else if (item === "]") middle === undefined ? (sum = -1) : middle--;
else if (item === ")") small === undefined ? (sum = -1) : small--;
}
if (big === 0 && middle === 0 && small === 0) distinction = true;
let save = s[0];
s = s.slice(1);
s += save;
if (distinction) {
result++;
distinction = false;
}
}
return result;
}
이렇게 하면 42.9점을 맞는다.
14개중에 8개가 틀릴 것이다.
스택이아니라 +1 -1 로하면 어디선가 꼬이는 것 같다.
그래서 결국 전부 갈아 엎고 맨 위에있는 것 처럼 작성해줬다.
실수한 점
1. 논리연산자
if문에서 여러개를 할때는 아래처럼해야하는데 잘못했다.
예전에 실수해서 써놓았는 데 그새 까먹었나보다 다시 보자.
if (s[0] === "}" || s[0] === ")" || s[0] === "]") // 정상
if (s[0] === "}" || ")" || "]") // 비정상
https://html-jc.tistory.com/357
2. 정규표현식
if(array.includes("[]")) array = array.replace(/\[]/g, "")
if(array.includes("()")) array = array.replace(/\(\)/g, "")
[]을 표현하고 싶으면 꼭 \을 써줘야한다.
그리고 괄호는 각각 써줘야 오류가 없다.
다른 사람 풀이
function solution(s) {
if(s.length % 2 === 1) return 0;
let count = 0;
const mapping = { "}" : "{", "]" : "[", ")" : "("};
for(let i = 0; i < s.length; i++) {
const stack = [];
const rotate = s.slice(i) + s.slice(0, i);
let flag = true;
for(let j = 0; j < s.length; j++) {
if(rotate[j] === "[" || rotate[j] === "(" || rotate[j] === "{" )
stack.push(rotate[j]);
else {
const last = stack.pop();
if(last !== mapping[rotate[j]]) {
flag = false
break;
}
}
}
if(flag) count++;
}
return count;
}
와 스택을 너무 잘 활용한 풀이 같다.
특히 mapping이 진짜 아이디어 같다.
처음에 if문은 홀수이면 바로 0을 return한다.
하나라도 괄호가 되지않으면 소용없기때문이다.
for문에서는
rotate를 통해서 s 문자열을 계속 회전하게 만든다. ( 이것도 진짜 아이디어다 어떻게 이렇게 할 생각을 한거지 ?)
그리고 flag가 true이면 count가 시작된다.
이중 for문에서는 rotate된 문자열에서 하나하나 확인하는 작업을 한다.
일단 { [ ( 이렇게 된 것을 stack에 담는다.
만약 이게 아니라면 두 가지 경우다
하나는 ) ] } 시작되거나 이미 스택에 담겨있는 상태에서 ) ] } 일 것이다
전자는 바로 break될것이고 후자라면 스택 맨 뒤에서 추출한 뒤 ( 이 추출한 것은 ( { [ 중 하나일 것이다. 이게 last에 할당된다.)
이 last와 mapping[rotate[j]]이 같은지 확인 작업을 한다. lotate[j]는 ] ) } 중 하나기에 mapping을 하면 짝이 찾아진다. ( 이건 진짜 대박)
그리고 같지 않을 때만 flag = false가 되고 break가 된다.
이 과정을 다 거치면 답이 나온다.
정말 코드를 잘 짠것 같다.
'알고리즘 > 프로그래머스 - JS' 카테고리의 다른 글
[프로그래머스] level.2 튜플 (0) | 2022.10.17 |
---|---|
[프로그래머스 - JS] level.2 n^2 배열 자르기 (0) | 2022.10.17 |
[프로그래머스] level.2 H-index (1) | 2022.10.11 |
[프로그래머스] level.2 행렬의 곱셈 (0) | 2022.10.11 |
[프로그래머스] level.2 [1차] 캐시 (0) | 2022.10.06 |