In a nutshell:
N
is an integer that represents a number of counters and the max counter allowed;A
is an array that represents the operation done on a specific counter (for example, if A[0]
is 1
and N
is 3
, we need to add 1
to counter[0]
);A
is N+1
, all elements of the counter
should be changed to the largest number in the counter
array.I submitted the code I wrote and got only 60% in performance. Why is that? Any way I should approach a problem next time to make it more efficient? How can I improve?
function solution(N,A){
let counters = Array(N).fill(0);
let maxCounter = 0;
for(i=0;i<A.length;i++){
if(A[i]<=N){
counters[A[i]-1]++
if(counters[A[i]-1]>maxCounter){maxCounter = counters[A[i]-1]};
}
else if(A[i]===N+1){
counters = Array(N).fill(maxCounter)
}
}
return counters
}
Edit: I didn't know that this website wasn't meant for questions regarding code improvement, thanks, I will ask somewhere else.
The 60%
score for efficiency is because of the two last test cases where over 10,000
"max counter" operations get performed. https://app.codility.com/demo/results/trainingA86B4F-NDB/
Each of those operations has to iterate through the counter
array, which may have as many as 100,000
elements. That works out to a total of 1 billion
writes, so the reason for the performance problem comes quickly in sight.
To improve this and bring this number down, we can eliminate the needless consecutive "max counter" operations by, for example, introducing a flag denoting whether the counter
array is already maxed and there is no need to iterate through it all over again.
Sample code:
const solution = (n, arr) => {
const counter = new Array(n).fill(0);
let max = 0, counterMaxed = false;
for (let curr of arr) {
if (curr > n) {
if (!counterMaxed) { counter.fill(max); counterMaxed = true; }
continue;
}
curr--; counter[curr]++; counterMaxed = false;
if (counter[curr] > max) { max = counter[curr]; }
}
return counter;
};
This gets a straight 100%
score:
https://app.codility.com/demo/results/training3H48RM-6EG/