I have the following problem:
You are given N counters, initially set to 0, and you have two possible operations on them:
Swift solution 100%
public func solution(_ N : Int, _ A : inout [Int]) -> [Int] {
// write your code in Swift 4.2.1 (Linux)
var solution = Array.init(repeating: 0, count: N)
var max = 0
var actualMaxValue = 0
for obj in A {
if (obj <= N && obj >= 1 ) {
if solution[obj-1] < actualMaxValue {
solution [obj-1] = actualMaxValue + 1
} else {
solution[obj-1] += 1
}
if (solution[obj-1] > max) {
max = solution[obj-1]
}
}
else if obj == N+1 {
actualMaxValue = max
}
}
for (index, value) in solution.enumerated() {
if value < actualMaxValue {
solution[index] = actualMaxValue
}
}
return solution
}
ES6
const solution = (n, a) => {
// Initialize to zero
let counter = new Array(n);
for(let i = 0 ; i < n ; i++ ){
counter[i] = 0;
}
let max = 0;
for(let j = 0 ; j < a.length ; j++ ){
const item = a[j];
if( item > n) {
for(let i = 0 ; i < n ; i++ ){
counter[i] = max;
}
}
else{
counter[item-1]++;
if(max < counter[item-1])
{
max = counter[item-1];
}
}
}
return counter;
};
The key is that [0] * N is an N operation. If that exists in a for loop it will become N*M. Tested in Codility 100%
# you can write to stdout for debugging purposes, e.g.
# print "this is a debug message"
def solution(N, A):
# write your code in Python 2.7
count = [0] * N
maxCounter = 0
minCounter = 0
for x in A:
if x <= N and x >= 1:
count[x-1] = max(count[x-1], minCounter) + 1
if maxCounter < count[x-1]:
maxCounter = count[x-1]
if x == N + 1:
minCounter = maxCounter
for i in xrange(N):
count[i] = max(count[i], minValue)
return count
A 100% JavaScript solution
function solution(N, A) {
// initialize all counters to 0
let counters = Array(N).fill(0)
// The maximum value of the counter is 0
let max = 0
// This variable will determine if an increment all operation has been encountered
// and its value determines the maximum increment all operation encountered so far
// for start it is 0, and we will set it to the value of max when A[i] == N + 1
let max_all = 0
for(let i = 0; i < A.length; i++) {
if(A[i] <= counters.length) {
// if the value of A[i] is 1, we have to increment c[0]
// and hence the following index
const c_index = A[i] - 1
// if max all operation was found previously,
// we have to set it here, because we are not setting anything in the else section
// we are just setting a flag in the else section
// if its value however is greater than max_all, it probably was already maxed
// and later incremented, therefore we will skip it
if(counters[c_index] < max_all) counters[c_index] = max_all
// do the increment here
const v = ++counters[c_index]
// update the max if the current value is max
max = v > max ? v : max
}
// this is straight forward
else max_all = max
}
// if there are remaining items that have not been set to max_all inside the loop
// we will update them here.
// and we are updating them here instead of inside the for loop in the else section
// to make the running time better. If updated inside the loop, we will have a running time of M * N
// however here it's something like (M + N) ~ O(N)
if(max_all) counters = counters.map(v => v < max_all ? max_all : v)
// return the counters
return counters
}
Here is an implementation in PHP:
function solution($N, $A) {
$output = array_fill(0, $N, 0);
$maxCounter = 0;
$minCounter = 0;
foreach ($A as $number) {
if($number === $N + 1) {
$minCounter = $maxCounter;
} else if($number <= $N) {
$number--;
if($minCounter > $output[$number]) {
$output[$number] = $minCounter;
}
$output[$number]++;
if($output[$number] > $maxCounter) $maxCounter = $output[$number];
}
}
foreach ($output as $index => $number) {
if($number < $minCounter) $output[$index] = $minCounter;
}
// var_dump($output);
return $output;
}
This is what I came up with, but I am not sure if it works 100%:
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
{
// inefficiency here
//for (int i = 0; i < result.Length; i++)
// result[i] = maximum;
resetLimit = maximum;
}
}
for (int i = 0; i < result.Length; i++)
result[i] = Math.Max(resetLimit, result[i]);
return result;
}