Algorithm: Max Counters

后端 未结 22 1598
孤城傲影
孤城傲影 2021-02-04 07:40

I have the following problem:

You are given N counters, initially set to 0, and you have two possible operations on them:

  • increase(X) − counter X is increa
相关标签:
22条回答
  • 2021-02-04 08:15
    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
    
    0 讨论(0)
  • 2021-02-04 08:17

    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
    
    0 讨论(0)
  • 2021-02-04 08:17

    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.

    0 讨论(0)
  • 2021-02-04 08:17
    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...

    0 讨论(0)
  • 2021-02-04 08:17

    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/

    0 讨论(0)
  • 2021-02-04 08:20

    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.

    0 讨论(0)
提交回复
热议问题