这种Max Counters编码挑战解决方案有什么问题

时间:2013-12-10 22:38:38

标签: python arrays algorithm

所以我一直在进行关于贪婪的测试,并且对“Max Counters”(链接https://codility.com/demo/take-sample-test/max_counters)感到有点困惑。我的第一个也是显而易见的解决方案是:

def solution(N, A):

    counters = N * [0];    

    for a in A:
        if 1 <= a <= N:
            counters[a - 1] += 1;
        elif a == N + 1:
            counters = N * [max(counters)];

    return counters

工作正常,但由于每次调用max计数器填充整个数组,所以需要花费太多时间。

所以我提出了以下解决方案,它似乎适用于小输入,但随机提供中等和大的错误结果。

def solution(N, A):

    counters = N * [0];
    current_max = 0;
    last_update = 0;

    for a in A:
        if 1 <= a <= N:
            counters[a - 1] += 1;

            if counters[a - 1] < last_update:
                counters[a - 1] = last_update + 1;

            if counters[a - 1] > current_max:
                current_max = counters[a - 1];

        elif a == N + 1:
            last_update = current_max;

    for i in xrange(len(counters)):
        if counters[i] < last_update:
            counters[i] = last_update;           

    return counters

我似乎无法弄清楚它有什么问题。

修改:结果 - http://codility.com/demo/results/demoQA7BVQ-NQT/

14 个答案:

答案 0 :(得分:9)

检查一下(python,获得100分):

每次你得到指令将它们全部提升到一个新的最小值时,秘诀就是不更新所有的计数器。这导致每次都涉及每个计数器的操作,并且是~60%得分和100%得分之间的差异。

相反,通过跟踪当前的最小值和最大值来避免此命中;为您访问的每个柜台使用和更新它们。

然后,在处理完所有指令之后,因为可能存在自上次更新所有指令以来未经过他们自己的个人更新的计数器,所以通过计数器本身并确保它们处于最小值。

def solution(N, A):
    res = [0] * N
    max_val = 0
    last_update = 0
    n1 = N+1
    for i in A:
        if i < n1:
            if res[i-1] < last_update:
                res[i-1] = last_update

            res[i-1]+=1

            if res[i-1] > max_val:
                max_val = res[i-1]
        else:
            last_update = max_val

    for i in xrange(len(res)):
        if res[i] < last_update:
            res[i] = last_update

    return res

http://codility.com/demo/results/demoF3AMPT-FVN/

答案 1 :(得分:1)

这里有一个问题:

counters[a - 1] += 1
if counters[a - 1] < last_update:
    counters[a - 1] = last_update + 1

如果counters[a - 1]last_update - 1,该怎么办?

答案 2 :(得分:1)

你可以看看我的解决方案(用C#编写):

public static int[] solution(int N, int[] A)
    {
        // write your code in C# with .NET 2.0
        var counters = new int[N];
        var defaultValueToInitialize = 0;
        var maxElement = 0;


        //initializing the counters values, without increasing the N+1 actions
        foreach (var num in A)
        {
            if (num == N + 1)
            {
                defaultValueToInitialize = maxElement;
                counters = new int[N];
            }
            else
            {
                counters[num - 1]++;
                if (counters[num - 1] + defaultValueToInitialize > maxElement)
                    maxElement = counters[num - 1] + defaultValueToInitialize;
            }

        }

        //adding the increased default value to each cell

        for (int i = 0; i < counters.Length; i++)
        {
            counters[i] += defaultValueToInitialize;
        }

        return counters;
    }

答案 3 :(得分:1)

在Ruby中考虑这个100/100解决方案:

# Algorithm:
#
# * Maintain a maximum value.
# * For each `increase(X)` command update respective counter.
# * For each `max_counter` command save the current max as `set_max` for later use.
# * Once the loop is over, make an adjustment pass to set all values less than `set_max` to `set_max`.
def solution(n, commands)
  max = set_max = 0
  counters = Array.new(n, 0)

  commands.each do |cmd|
    if cmd <= n
      # This is an `increase(X)` command.
      value = [counters[cmd - 1], set_max].max + 1
      counters[cmd - 1] = value
      max = [value, max].max
    else
      # This is a `max_counter` command.
      # Just update `set_max`.
      set_max = max
    end
  end

  # Finalize -- set counters less than `set_max` to `set_max`.
  counters.map! {|value| [value, set_max].max}

  # Result.
  counters
end

#--------------------------------------- Tests

def test
  sets = []
  sets << ["1", [1], 1, [1]]
  sets << ["sample", [3, 2, 2, 4, 2], 5, [3, 4, 4, 6, 1, 4, 4]]

  sets.each do |name, expected, n, commands|
    out = solution(n, commands)
    raise "FAILURE at test #{name.inspect}: #{out.inspect} != #{expected.inspect}" if out != expected
  end

  puts "SUCCESS: All tests passed"
end

答案 4 :(得分:0)

我的python版本只得到66分,因为它对后来的测试来说有点太慢了。

def solution(N, A):
    counters = [0 for x in range(N)]
    for elem in A:
        if elem > N:
            cmax = max(counters)
            counters = [cmax for x in range(N)]
        else:
            counters[elem-1] += 1
    return counters

答案 5 :(得分:0)

100/100 C解决方案

struct Results solution(int N, int A[], int M) {
    struct Results result;
    int *cnts = calloc(N,sizeof(int));
    int i=0,maxcnt=0,j=0,lastcnt=0;
    for (i=0;i<M;i++) {
        if (A[i]<=N && A[i]>=1) {
            if (cnts[A[i]-1] < lastcnt)
                cnts[A[i]-1] = lastcnt + 1;
            else
                cnts[A[i]-1] += 1;
            if (cnts[A[i]-1] > maxcnt)
                maxcnt = cnts[A[i]-1];
        }
        if (A[i] == N+1) {
                lastcnt = maxcnt;
        }
    }
    for (j=0;j<N;j++) {
            if (cnts[j]<lastcnt)
                cnts[j] = lastcnt;
    }
    result.C = cnts;
    result.L = N;
    return result;
}

答案 6 :(得分:0)

我在java中有77%的解决方案:

有人能建议我100%的解决方案吗?

 import java.util.Arrays;
 class Solution {
 public int[] solution(int N, int[] A) {

 int maxCounter=0;
 int[] B=new int[N];

 for(int i=0;i<A.length;i++){

 if(A[i]==N+1){
 setMaximum(B, maxCounter);
 }
 else{
 B[A[i]-1]++;               
 if(maxCounter<B[A[i]-1]){
 maxCounter=B[A[i]-1];
 }

 }
 }
 return B;
 }

 void setMaximum(int[] B,int maxValue){
 for(int i=0;i<B.length;i++){
 B[i]=maxValue;
 }

 }
 }

答案 7 :(得分:0)

C中的MaxCounters解决方案

struct Results solution(int N, int A[], int M) {
    struct Results result;
    // write your code in C90
    int i,k=0,max_v=0;

    result.C =(int*)(malloc(N*sizeof(int)));
    result.L = N;   
    memset(result.C, 0, N*sizeof(int));  

    for(i=0;i<M;i++)
    {      
        if (A[i] > N)    
            max_v=k;
        else
        {
            if(result.C[A[i]-1] < max_v)
                result.C[A[i]-1]=max_v;

            result.C[A[i]-1]+=1; 

            if(result.C[A[i]-1] > k)
                k=result.C[A[i]-1];
        }   
    }

    for(i=0;i<N;i++)
    {
        if(result.C[i] < max_v)
            result.C[i]=max_v;
    }

    return result;
}

答案 8 :(得分:0)

Javascript 100/100

&#13;
&#13;
function solution(N, A) {
    
    var j, len = A.length, lastBase = 0, max = 0, 
        counters = [], n1 = N+1;

    for(j=0; j<N; j+=1){
        counters[j]=0; //initArray
    }
    
    for(j=0; j < len; j+=1){
        if(A[j]<n1){
            if(counters[A[j]-1] < lastBase) {
                counters[A[j]-1] = lastBase;
            }
            counters[A[j]-1] += 1;
            if(max < counters[A[j]-1]) {
                max = counters[A[j]-1];
            }
        } else {
            lastBase = max;
        }
    }
    
    for(j=0; j<N; j+=1){
        if(counters[j] < lastBase) {
            counters[j] = lastBase;
        }
    }
    
    return counters;
    
}
&#13;
&#13;
&#13;

答案 9 :(得分:0)

这是@ jacoor解决方案的修改版本,其中包含更多惯用的python和变量名称以及if语句条件更能反映问题描述。

def fast_solution(N, A):
    counters = [0] * N
    max_counter = 0
    last_update = 0

    for K,X in enumerate(A): # O(M)
        if 1 <= X <= N:
            counters[X-1] = max(counters[X-1], last_update)
            counters[X-1] += 1
            max_counter = max(counters[X-1], max_counter)
        elif A[K] == (N + 1):
            last_update = max_counter

    for i in xrange(N): # O(N)
        counters[i] = max(counters[i], last_update)

    return counters

https://codility.com/demo/results/demo6KPS7K-87N/

答案 10 :(得分:0)

Java solution -->


    public int[] solution(int N, int[] A) {
        // write your code in Java SE 8
        int[] counter = new int[N];
        int maxCounter = 0;
        int pos;
        int last_max=0;
        for (int i = 0; i < A.length; i++) {
            if (A[i] <= N) {
                pos = A[i];

                if (counter[pos - 1] < last_max)
                    counter[pos - 1] = last_max;
                counter[pos - 1] += 1;

                if (maxCounter < counter[pos - 1])
                    maxCounter = counter[pos - 1];
            }
            else{
                last_max=maxCounter;
            }
        }

        for (int i = 0; i < counter.length; i++) {
            if (counter[i] < last_max)
                counter[i] = last_max;
        }
        return counter;
    }

答案 11 :(得分:0)

C ++ 100/100

关键是IGNORE问题中的样本迭代,它将引导您进入O(m * n)时间复杂度解决方案。

vector<int> solution(int N, vector<int> &A) {
// write your code in C++11

vector<int> counters(N,0);

int last_reset = 0, max_count = 0;

for( unsigned int a=0; a < A.size(); ++a)
{
     int current_int = A.at (a);

     if (current_int == (N+1))
     {
        last_reset = max_count;
     }
     else
     {
        unsigned int counter_index = current_int - 1;

        if ( counters.at (counter_index) < last_reset)
            counters.at (counter_index) = last_reset + 1;
        else
            ++counters.at (counter_index);
        if ( counters.at (counter_index) > max_count)
            max_count = counters.at (counter_index);
     }

}
for( unsigned int n=0; n < counters.size(); ++n)
{
    if ( counters.at (n) < last_reset)
        counters.at (n) = last_reset;
}
return counters;

}

答案 12 :(得分:0)

C# - 100/100解决方案

public int[] solution(int N, int[] A) {
    // write your code in C# 6.0 with .NET 4.5 (Mono)
    int[] counter = new int[N];
    int maxValue = 0;
    int minValue = 0;
    for(int i=0;i<A.Length;i++)
    {
        //less than or equal to length N
        if(A[i] <= N)
        {
            if(counter[A[i] - 1] < minValue)
            {
                counter[A[i] - 1] = minValue;
            }
            counter[A[i] - 1] += 1;
            if(counter[A[i] - 1] > maxValue)
            {
                maxValue = counter[A[i] - 1];
            }
        }
        else if(A[i] == N+1)
        {
            minValue = maxValue;
        }
    }
    for(int j=0;j<counter.Length;j++)
    {
        if(counter[j] < minValue)
        {
            counter[j] = minValue;
        }
    }
    return counter;
}

答案 13 :(得分:0)

这是Python中最短的解决方案:

def solution(N, A):
    out = [0 for _ in range(N)]
    for ele in A:
        if ele<=N: out[ele-1] += 1
        else: out = [max(out) for i in range(len(out))]           
    return out