-
[CodeKata] 프로그래머스: 1.15(토), 스타 수열Algorithm 2022. 1. 15. 20:58반응형
🥋 Oooth More!! (Level 3)
🧮 풀이
이후 나올 모범답안에 비해 민망할 정도로 긴 풀이라, 간단하게 설명하겠다...!!
문제전개에 충실하게, checkStarArr(스타수열 판정), combination(부분수열의 조합) 함수들을 만들고 이에 맞는 부분수열을 찾는 방법이다.
const checkStarArr = (a) => { let common = [a[0], a[1]]; for (let i = 0 ; i < a.length ; i+=2) { if (a[i] === a[i+1]) return false; common = common.filter(e => e === a[i] || e === a[i+1]); if (!common.length) return false; } return true; } function combination(arr, num){ const res = []; if(num === 1) return arr.map((v) => [v]); arr.forEach((v, idx, arr) => { const rest = arr.slice(idx+1); const combinations = combination(rest, num-1); const attach = combinations.map((combination) => [v, ...combination]); res.push(...attach); }) return res; } function solution(a) { const len = a.length; if (len % 2 === 0 && checkStarArr(a)) return len; if (len < 2) return 0; let count = len % 2 === 0 ? len-2 : len-1; while (count > 2) { for (let partArr of combination(a,count)) { if (checkStarArr(partArr)) { console.log(partArr) return count } } count -= 2; } return 2; }
🖇 리뷰
function solution (a) { let answer = 0; const counts = a.reduce((acc, cur) => { acc[cur] ? acc[cur][1]++ : acc[cur] = [cur, 1]; return acc; }, []).filter(el => el).sort((a, b) => b[1]-a[1]); for(let i = 0; i < counts.length; i++) { if(answer >= counts[i][1]) continue; let count = 0; for(let j = 0; j < a.length; j++) { if(a[j+1] === undefined) continue; if(a[j] === a[j+1]) continue; if(a[j] !== counts[i][0] && a[j+1] !== counts[i][0]) continue; count++; j++; } answer = Math.max(answer, count); } return answer * 2; }
- answer는 정답을 누적할 변수이다. 여기에는 스타수열을 이루는 쌍의 갯수가 누적되므로, 마지막에 *2(총 갯수) 처리를 해야한다.
- counts는 a배열에서 [요소, 사용횟수] 를 가장 많이 사용한 순으로 저장한 배열이다. reduce()를 통해 계산하며, acc의 (요소)번째 인덱스에 정보를 저장하기 때문에, 이후 filter()로 사이사이 undefined를 정리해주는 것이다.
- counts를 순회하며 answer에 정답을 누적한다. 우선, 사용횟수가 answer보다 작다면 정답이 되지 않으므로 continue로 넘어간다.
- 다음으로, 현재조건([요소, 사용횟수]) 와 a배열을 비교한다. count는 스타수열 쌍의 갯수이며, a배열을 순회하며 아래 연산을 한다.
- 1) 다음요소가 없거나, 2) 요소쌍이 서로 같거나, 3) 요소쌍 모두 현재조건 요소와 다른 경우 부적절하므로 continue로 넘어간다.
- 이를 만족한다면, [a[j], a[j+1]]은 스타수열이 되므로 count에 1을 더한다. 그리고, 다다음 요소를 보기위해 인덱스(j)에 1을 더 더해준다.
- 위 계산을 완료한 뒤, count와 answer 중 최대값으로 최신화를 한다. 이는 스타수열 쌍의 갯수이므로, 정답을 반환할 땐 2를 곱한다.
문제의 흐름에 너무 충실한 로직을 짜면 그만큼 효율성이 떨어진다는 것을 다시금 느꼈다.
그대로 구현하는 알고리즘을 짜기보다는, 정답을 위한 조건들을 고려해서 이를 찾을 수 있는 최적의 방법을 고민해버릇 해야겠다!
반응형'Algorithm' 카테고리의 다른 글
[CodeKata] 프로그래머스(Lv3) : 숫자 게임 (0) 2022.01.30 [CodeKata] 프로그래머스: 1.23(일), 가장 긴 펠린드롬 (0) 2022.01.23 [CodeKata] 프로그래머스: 1.10(월), 기지국 설치 (0) 2022.01.10 [CodeKata] 프로그래머스: 12.28(화), 풍선 터트리기 (0) 2021.12.30 [CodeKata] 프로그래머스: 12.19(일), 블록 이동하기 (0) 2021.12.19