먼저 작성한 코드
function solution(s) {
var answer = 0;
let closerObj = { '[' : ']', '{' : '}', '(': ')' }
for (let i=0; i<s.length; i++) {
if (s.length%2 === 1) return 0;
//괄호종류마다 닫을 필요가 있는 개수를 저장하는 객체
let closerMap = { ']': 0, '}' : 0, ')' : 0 }
let targetStr = s.slice(i) + s.slice(0, i)
for (let j = 0; j<targetStr.length; j++) {
let switchFlag = false
let targetWord = targetStr[j]
if (targetWord === '[') {
closerMap[']'] = closerMap[']'] + 1
continue;
}
if (targetWord === ']') {
closerMap[']'] = closerMap[']'] - 1
if (closerMap[']'] < 0) {
switchFlag = true
break;
}
continue;
}
if (targetWord === '{') {
closerMap['}'] = closerMap['}'] + 1
continue;
}
if (targetWord === '}') {
closerMap['}'] = closerMap['}'] - 1
if (closerMap['}'] < 0) {
switchFlag = true
break;
}
continue;
}
if (targetWord === '(') {
closerMap[')'] = closerMap[')'] + 1
continue;
}
if (targetWord === ')') {
closerMap[')'] = closerMap[')'] - 1
if (closerMap[')'] < 0) {
switchFlag = true
break;
}
continue;
}
if (switchFlag) break;
}
let flag = true
//닫을필요수 객체에서 값이 0이 아닌값이 있다면 answer에 경우의수를 더하지 않는다.
Object.keys(closerMap).forEach((key) => {
if (closerMap[key] !== 0) {
flag = false
}
})
if (flag) {answer++};
}
return answer;
}
반복에따라 회전한 문자열 targetStr의 한 단어마다 어떤 괄호인지 검사하여 closerMap의 해당 괄호의 닫는괄호에 닫아야하는 개수를 더하거나 뺀다.
만약 타겟단어가 닫는괄호인데, 객체에서 해당 값의 1을 뺐을 때 음수라면 바로 반복을 중단하고 다음 회전으로 넘어가는 방식이었다.
14번은 "{(})"인 케이스이다. 괄호를 열고 닫는 순서에 대한 피드백없이 여닫는 개수만 확인하다보니 생긴 문제였다.
싹 갈아엎어야 한다. 괄호가 들어오는 순서에 대한 검사가 전혀 없기 때문이다.
두번쨰로 작성한 코드
function solution(s) {
var answer = 0;
for (let i = 0; i<s.length; i++) {
let rotated = s.slice(i) + s.slice(0, i)
let flag = true;
let openClosers = [];
for (const word of rotated) {
//여는걸 배열에 순서대로 저장하고, 맨 뒤의 값을 닫는것과 비교한다.
if (word === "[" || word === "{" || word === "(") {
openClosers.push(word)
} else {
//닫는 괄호일 경우에 openClosers의 맨 마지막과 알맞는지 비교, 안맞으면 {(})이런 모양이므로 break;
let lastOpenCloser = openClosers.pop()
//일치할경우 다음 반복으로
if (lastOpenCloser === '{' && word === '}') continue;
if (lastOpenCloser === '(' && word === ')') continue;
if (lastOpenCloser === '[' && word === ']') continue;
//일치하지 않을경우 flag를 false로
flag = false
}
}
//모든 글자를 돌았을 때 flag에 따라 경우를 더할지 결정
if (flag) answer++
}
return answer;
}
여는괄호를 따로 배열에 순서대로 넣어두고, 닫는괄호가 나왔을 때 여는괄호배열의 제일 마지막(제일먼저 닫아야하는 괄호)와 알맞는지 판단하고 적절한 경우 다음반복으로, 아닌경우 flag를 false로 바꾼다.
이 경우 ' (){{ " 이 케이스를 잡아내지 못한다.
맨 처음 작성했을 때 음수체크하는 부분을 넣지 못한 것이다.
세번쨰로 작성한 코드
function solution(s) {
var answer = 0;
for (let i = 0; i<s.length; i++) {
console.log(`---${i}---`)
let backToFront = s.slice(i)
let frontToBack = s.slice(0, i)
// let rotated = backToFront + frontToBack
let rotated = s.slice(i) + s.slice(0, i)
let flag = true;
let openClosers = [];
for (const word of rotated) {
//여는걸 배열에 순서대로 저장하고, 맨 뒤의 값을 닫는것과 비교한다.
if (word === "[" || word === "{" || word === "(") {
openClosers.push(word)
} else {
//닫는 괄호일 경우에 openClosers의 맨 마지막과 알맞는지 비교, 안맞으면 {(})이런 모양이므로 break;
let lastOpenCloser = openClosers.pop()
console.log('last= ', lastOpenCloser)
console.log('targetWord= ', word)
console.log('isFalsy= ', lastOpenCloser ? 'true' : 'false')
//닫는괄호인데 openClosers에 아무것도 없을 때는?
//일치할경우 다음 반복으로
if (!lastOpenCloser && (lastOpenCloser === '{' && word === '}')) continue;
if (!lastOpenCloser && (lastOpenCloser === '(' && word === ')')) continue;
if (!lastOpenCloser && (lastOpenCloser === '[' && word === ']')) continue;
//일치하지 않을경우 flag를 false로
flag = false
}
}
// (){{
// ){{(
// {{()
// {()}
//모든 글자를 돌았을 때 flag에 따라 경우를 더할지 결정
console.log('flag= ', flag)
if (flag) answer++
console.log('answer= ', answer)
console.log(`---${i}---`)
}
return answer;
}
하다가 포기했다. openClosers배열이 비어있을 때 닫는 괄호가 나오면 flag를 바꾸고 break한다 라는 것을 작성하고 싶었는데 실패했다.
마지막으로 작성한 코드
function solution(s) {
var answer = 0;
if (s.length%2 === 1) return 0;
//각 괄호의 여닫는 횟수가 일치하는지 확인하는 Map
let sMap = new Map()
sMap.set('{', 0).set('}', 0).set('[', 0).set(']', 0).set('(', 0).set(')', 0)
for (let j = 0; j<s.length; j++) {
sMap.set(s[j], sMap.get(s[j])+1)
}
if (sMap.get('{') !== sMap.get('}')) return 0;
if (sMap.get('[') !== sMap.get(']')) return 0;
if (sMap.get('(') !== sMap.get(')')) return 0;
for (let i = 0; i<s.length; i++) {
let rotated = s.slice(i) + s.slice(0, i)
let flag = true;
let openClosers = [];
for (const word of rotated) {
if (word === "[" || word === "{" || word === "(") {
openClosers.push(word)
} else {
let lastOpenCloser = openClosers.pop()
if (lastOpenCloser === '{' && word === '}') continue;
if (lastOpenCloser === '(' && word === ')') continue;
if (lastOpenCloser === '[' && word === ']') continue;
flag = false
}
}
if (flag) answer++
}
return answer;
}
각 괄호의 여닫는 개수를 저장하는 sMap을 만들어 짝지어진 괄호의 개수를 비교하고 어떤 괄호라도 맞지않으면 어떻게 회전시키더라도 완벽한 괄호를 만들어내지 못하므로 0을 리턴하는 예외처리를 해주었다.
성공
'2차 공부 > 알고리즘' 카테고리의 다른 글
할인 행사 (0) | 2024.07.23 |
---|---|
n^2 배열 자르기 (0) | 2024.07.19 |
이진 변환 반복하기 (0) | 2024.07.09 |
JadenCase 문자열 만들기 (0) | 2024.07.08 |
최댓값과 최소값 (0) | 2024.07.05 |