[20210618] Counting Elements - MaxCounters (in Codility)
문제 정보
N개의 counter가 존재하며, 해당 counter들은 순서가 존재한다. M개의 counter 위치 정보가 저장된 배열(A)이 있으며, 이를 순회하며 위치 정보와 일치하는 counter의 값을 증가시킨다. 만약 N+1의 값이 나오면 counter의 모든 값을 counter에서 가장 큰 값으로 통일한다.
https://app.codility.com/programmers/lessons/4-counting_elements/max_counters/
직면한 문제
효율성에서 O(N * M)이 나왔으며, 효율성을 통과하지 못했다.
처음 제출한 코드는
for(int num : A) {
if(num == N + 1) {
max = findMax(counters);
Arrays.fill(counters, max);
} else {
counters[num]++;
}
}
이었다.
처음 for문에서 O(M)의 복잡도, Arrays.fill에서 O(N)의 복잡도가 나오므로, 결론적으로 이는 O(N * M) 복잡도였던 것이다.
해결 방법
여기서 최적화를 하기위해서는 Arrays.fill()을 사용하지 않아야 했다.
그래서 나온 코드가
for(int num : A) {
if(num == N + 1) {
boundary = max;
} else {
if(counters[num] < boundary) counters[num] = boundary;
counters[num]++;
max = Math.max(max, counters);
}
}
for(int i = 0; i < counters.length; i++) {
if(counters[i] < boundary) counters[num] = boundary;
}
boundary라는 변수를 사용하여 전체 변수의 기준 값을 저장하였고, 전체의 값이 최대값으로 변경해야 하더라도 즉시 배열 전체를 초기화 하지 않고, 필요 시에만 초기화 해주면서, 처음 for문에서 O(M)의 복잡도, 두 번째 for문에서 O(N)의 복잡도로 전체 시간복잡도는 O(M + N)으로 줄일 수 있었다.