I have the following problem:
You are given N counters, initially set to 0, and you have two possible operations on them:
def solution(N, A):
res = [0] * N
maxV, minV = 0, 0
for x in A:
if 1 <= x <= N:
res[x-1] = max(res[x-1], minV) + 1
maxV = max(maxV, res[x-1])
else: minV = maxV
for i in range(N):
res[i] = max(res[i], minV)
return res
Here's a solution I came up with in Python (100/100 on codility); it's a little different than others I've seen on here so thought I'd share:
def solution(N, A):
count = [0] * N
max_counter = [i for i, a in enumerate(A) if a == N+1]
if len(max_counter) == len(A):
return count
if max_counter:
mode = 0
for i, m in enumerate(max_counter):
if m == 0 or m - max_counter[i-1] == 1:
continue
subcount = {}
if i == 0:
for k in A[:m]:
if k not in subcount:
subcount[k] = 1
else:
subcount[k] += 1
else:
for k in A[max_counter[i-1]+1:m]:
if k not in subcount:
subcount[k] = 1
else:
subcount[k] += 1
mode += max(subcount.values())
count = [mode] * N
for k in A[max_counter[-1]+1:]:
count[k-1] += 1
else:
for k in A:
count[k-1] += 1
return count
Let's see...
public int[] Solution(int N, int[] A)
{
int[] data = new int[N];
int maxval = 0;
int baseval = 0;
for (int K = 0; K < A.length; K++)
{
int index = A[K] - 1;
if (index < 0 || index > N)
throw new InvalidOperationException();
if (index < N)
maxval = baseval + Math.Max(maxval, ++data[index]);
else
{
baseval = maxval;
data = new int[N];
}
}
for (int K = 0; K < N; K++)
data[K] += baseval;
return data;
}
I think that's O(N+K)
. Depends on how you count the Order of re-initializing the array.
public int[] counters(int N, int[] A)
{
int[] count = new int[N];
int maxCount = 0;
int setAll = 0;
for (int i = 0; i < A.Length; i++)
{
if (A[i] == N + 1)
{
setAll += maxCount;
maxCount = 0;
count = new int[N];
}
else
{
count[A[i] - 1] += 1;
if (count[A[i] - 1] > maxCount)
{
maxCount = count[A[i] - 1];
}
}
}
for (int j = 0; j < count.Length; j++)
{
count[j] += setAll;
}
return count;
}
I think this is O(N+K), but codility say its O(N*K)? Would appreciate if anyone could explain which is correct...
Here is Scala version, 100% on codility:
import java.util
def solution(N: Int, A: Array[Int]): Array[Int] = {
var counters = new Array[Int](N)
var maxCounter = 0
for(ind <- 0 to A.length-1){
if(A(ind) == (N+1)){
//all to max
util.Arrays.fill(counters,maxCounter)
}else{
//ind -1 cause array index start with 0 which is marked as 1 in the input data
counters(A(ind)-1) += 1
//update max counter if necessary
if(maxCounter< (counters(A(ind)-1))) maxCounter = (counters(A(ind)-1))
}
}
return counters
}
Performance: https://codility.com/demo/results/trainingKJT6Y3-74G/
Rue, I just ran this locally. Watched the counters myself. I used this algorithm:
public int[] solution(int N, int[] A)
{
int[] result = new int[N];
int maximum = 0;
int resetlimit = 0;
for (int K = 0; K < A.Length; K++)
{
if (A[K] < 1 || A[K] > N + 1)
{
throw new InvalidOperationException();
}
if (A[K] >= 1 && A[K] <= N)
{
if (result[A[K] - 1] < resetlimit)
{
result[A[K] - 1] = resetlimit + 1;
}
else
{
result[A[K] - 1]++;
}
if (result[A[K] - 1] > maximum)
{
maximum = result[A[K] - 1];
}
}
else
{
resetlimit = maximum;
result = Enumerable.Repeat(maximum, result.Length).ToArray();
}
}
//for (int i = 0; i < result.Length; i++)
//{
// result[i] = Math.Max(resetlimit, result[i]);
//}
return result;
}
}
looking at the problem and the result sets, you must include in the inefficient for loop in the else statement. The for loop outside does not replicate the 2nd operation
•if A[K] = N + 1 then operation K is max_counter.
In order for iteration A[3] = 6 to set result[] all to '2' you must load the result array with the maximum counter. Otherwise your return will never have (2,2,2,2,2) as the 4th example array shows.
I too must take a test to get my dream job so the little inefficiency here is important;
the statement
result = Enumerable.Repeat(maximum, result.Length).ToArray();
loads the array all in one shot so no inner loop and no inner efficiency. I think that is pretty close to the correct result sets. I'm surprised they didn't ask to return like a jagged array of the total return. Still, this codility test scares me a lot.