faster implementation of sum ( for Codility test )

前端 未结 22 2082
鱼传尺愫
鱼传尺愫 2021-02-04 11:47

How can the following simple implementation of sum be faster?

private long sum( int [] a, int begin, int end ) {
    if( a == null   ) {
        ret         


        
相关标签:
22条回答
  • 2021-02-04 12:22

    I don't believe the problem is in the code you provided, but somehow the bigger solution must be suboptimal. This code looks good for calculating the sum of one slice of the array, but maybe it's not what you need to solve the whole problem.

    0 讨论(0)
  • 2021-02-04 12:22
    private static int equi ( int[] A ) {
        if (A == null || A.length == 0)
         return -1;
     long tot = 0;
     int len = A.length;
     for(int i=0;i<len;i++)
         tot += A[i];
     if(tot == 0)
         return (len-1);
     long partTot = 0;
     for(int i=0;i<len-1;i++)
     {
      partTot += A[i];
      if(partTot*2+A[i+1] == tot)
       return i+1;
     }
     return -1;
    

    }

    I considered the array as a bilance so if the equilibrium index exist then half of the weight is on the left. So I only compare the partTot (partial total) x 2 with the total weight of the array. the Alg takes O(n) + O(n)

    0 讨论(0)
  • 2021-02-04 12:22

    This may be old, but here is solution in Golang with 100% pass rate:

    package solution
    
    func Solution(A []int) int {
        // write your code in Go 1.4
        var left int64
        var right int64
        var equi int
    
        equi = -1
        if len(A) == 0 {
            return equi
        }
    
        left = 0
        for _, el := range A {
            right += int64(el)
        }
    
        for i, el := range A {
            right -= int64(el)
            if left == right {
                equi = i
            }
            left += int64(el)
        }
    
        return equi
    }
    
    0 讨论(0)
  • 2021-02-04 12:23
    {In Pascal + Assembly}
    {$ASMMODE INTEL}
    function equi (A : Array of longint; n : longint ) : longint;
    var c:Longint;
        label noOverflow1;
        label noOverflow2;
        label ciclo;
        label fine;
        label Over;
        label tot;
    Begin
     Asm
        DEC n
        JS over
        XOR ECX, ECX   {Somma1}
        XOR EDI, EDI   {Somma2}
        XOR EAX, EAX
        MOV c, EDI
        MOV ESI, n
      tot:
        MOV EDX, A
        MOV EDX, [EDX+ESI*4]
        PUSH EDX
        ADD ECX, EDX
        JNO nooverflow1
        ADD c, ECX
        nooverflow1:
        DEC ESI
      JNS tot;
        SUB ECX, c
        SUB EDI, c
      ciclo:
        POP EDX
        SUB ECX, EDX
        CMP ECX, EDI
        JE fine
        ADD EDI, EDX
        JNO nooverflow2
        DEC EDI
        nooverflow2:
        CMP EAX, n
        JA over
        INC EAX
        JMP ciclo
        over:
          MOV EAX, -1
        fine:
      end;
    End;
    
    0 讨论(0)
  • 2021-02-04 12:24

    I don't think your problem is with the function that's summing the array, it's probably that you're summing the array WAY to frequently. If you simply sum the WHOLE array once, and then step through the array until you find the first equilibrium point you should decrease the execution time sufficiently.

    int equi ( int[] A ) {
        int equi = -1;
    
        long lower = 0;
        long upper = 0;
        foreach (int i in A)
            upper += i;
    
        for (int i = 0; i < A.Length; i++)
        {
            upper -= A[i];
            if (upper == lower)
            {
                equi = i;
                break;
            }
            else
                lower += A[i];
        }
    
        return equi;
    }
    
    0 讨论(0)
  • 2021-02-04 12:24

    In C# 3.0, my computer and my OS this is faster as long as you can guarantee that 4 consecutive numbers won't overflow the range of an int, probably because most additions are done using 32-bit math. However using a better algorithm usually provides higher speed up than any micro-optimization.

    Time for a 100 millon elements array:

    4999912596452418 -> 233ms (sum)

    4999912596452418 -> 126ms (sum2)

        private static long sum2(int[] a, int begin, int end)
        {
            if (a == null) { return 0; }
            long r = 0;
            int i = begin;
            for (; i < end - 3; i+=4)
            {
                //int t = ;
                r += a[i] + a[i + 1] + a[i + 2] + a[i + 3];
            }
            for (; i < end; i++) { r += a[i]; }
            return r;
        }
    
    0 讨论(0)
提交回复
热议问题