https://school.programmers.co.kr/learn/courses/30/lessons/131130
열린 적 없는 상자인 경우
-> 해당 인덱스의 open을 1로 변경하고, 이 상자가 포함된 그룹의 상자 개수를 표현하는 변수인 count를 하나 증가시킨다. 이후 상자에 들어있던 카드(cards[인덱스])를 확인하며 open이 1일 때까지 해당 작업을 반복한다.
그룹이 완성되면 count를 group 배열에 push한다.
열린 상자의 경우
-> 이미 해당 상자의 그룹은 계산 되었으므로, 다시 그룹을 구하는 것이 무의미하다. 따라서 open이 1인 경우, 확인하지 않고 그 다음 상자로 넘어간다.
위 작업을 마친 후, 그룹의 크기를 저장한 group 내에서 가장 큰 값 두 개의 곱을 반환한다.
오류 내용
테스트 케이스를 통과하였고, 정답을 제출했을 때에도 타임오버 없이 마무리 되었으나 2가지 케이스에서 오답을 발생시켰다.
로직 자체에 문제는 없으리라고 생각하고, 구현에 있어서의 구멍을 계속 확인하였다.
오류 이유 파악
스스로 오답을 찾지 못해 기술 매니저님의 도움을 받았다.
'로직은 타당해 보인다. 그러나 group의 큰 값 두 개를 받아오는 과정에서 무언가 잘못된 것 같다.'고 답변을 주셨다.
실제로, 매니저님이 문제의 주 작업이 되는 부분은 내 코드를 그대로 둔 후, 하단 최댓값 두 개를 뽑는 부분만 변경하였더니 문제없이 정답이 제출되었다.
나도 방법을 바꾸어 sort로 group을 내림차순 정렬한 후, 0번, 1번 인덱스의 숫자를 곱하거나, group의 길이가 1인 경우 0을 반환하도록 변경하여 정답을 제출하였다.
오류 수정
스터디 조원에게 내 코드를 설명하다가 오류를 찾게 되었다.
기존 최댓값 a, 그 다음 최댓값 b를 찾는 코드는 아래와 같았다.
let a = 0;
let b = 0;
for(let i = 0; i < group.length; i++){
if(group[i] > a ) a = group[i];
else if(group[i] > b) b = group[i];
}
가장 큰 값이어야하는 a보다 크면 a에 업데이트, a보다는 크지 않지만 b보다는 크면 b에 업데이트 하고자 하였다.
여기서 놓친 부분은, a가 업데이트 되는 순간에 기존에 있던 a 값은 b 값이 되어야 한다는 점이었다. 아주 단순한 부분인데 오히려 단순해서 틀릴리 없다고 단정지었다.
이미 정답을 제출한 후에 알아차리기는 했지만, 조원 덕분에 내 코드를 설명하며 어디서 실수했는지를 알 수 있게 되어 우선은 만족스럽다.
하단은 제출한 전체 코드이다.
function solution(cards) {
var answer = 0;
let open = new Array(cards.length);
let group = [];
for(let i = 0; i < cards.length; i++){
if(open[i] != 1){
let now = i;
let count = 0;
while(open[now] != 1){
open[now] = 1;
count++;
now = cards[now] - 1;
}
group.push(count)
}
}
group.sort(function(a, b) { return b - a; })
answer = group.length == 1 ? 0 : group[0] * group[1];
return answer;
}