Algorithm
[CodeKata] 프로그래머스: 1.15(토), 스타 수열
ttaeng_99
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를 곱한다.
문제의 흐름에 너무 충실한 로직을 짜면 그만큼 효율성이 떨어진다는 것을 다시금 느꼈다.
그대로 구현하는 알고리즘을 짜기보다는, 정답을 위한 조건들을 고려해서 이를 찾을 수 있는 최적의 방법을 고민해버릇 해야겠다!
반응형