代码之家  ›  专栏  ›  技术社区  ›  Nditah

如何对时间复杂度为大O(N)的循环中的数组部分求和

  •  0
  • Nditah  · 技术社区  · 8 年前

    我有一个函数,它根据数组被分割的位置P返回数组两部分之和之间的最小差。经测试,该程序的运行时间复杂度为O(N*N),性能为0%,但预期为O(N)。

    问题:我是否可以在这方面进行任何更改以提高性能?有没有更好的方法可以不使用子循环而对循环中的数组求和?谢谢

    任意整数P,0<<N、 将此磁带拆分为两个非空部分: A[0],A[1]。。。,A[P-1]和A[P],A[P+1]。。。,A[第1页]。

    这两部分之间的差值为: |(A[0]+A[1]+…+A[P 1])(A[P]+A[P+1]+…+A[N 1])|

    https://jsbin.com/mehisi/edit

    function solution(A) {
    
      'use strict';
    
      if(arguments.length === 1 && typeof A === "object" && A.length > 1 ){
        try{
          const N = A.length;
    
          let diff;
          for( let P =1 ; P < N ; P++) {
            // For each value of P, calc the difference 
            //|(A[0] + A[1] + ... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
    
            // use slice to prevent modification of oraginal copy
            var A2 = A.slice(0) ; 
            //splice array into two A1 and A2
            let A1 = A2.splice(0, P);  // All Element from start up to P
            console.log("From Array " + A  + " Remove "+ A1 + " Remaining " + A2);
            // reduce((a, b) => a + b, 0); 
            let diffp = Math.abs((A1.reduce(function(a, b) { return a + b; }, 0)) - 
                (A2.reduce(function(a, b) { return a + b; }, 0))) ;
    
            if(diff > diffp || diff === undefined ){
              diff = diffp ;
            }
            console.log(P + "Difference ="+ diff + " Instead of " + diffp + " \r\n " );
          }
    
          // Return the Minimum value of P
          return diff  ;
        }
        catch(err){
         console.log("Error: " + err );
        return 0 ; // undefined ;
        }
      }else{
         console.log("Invalid parameter(s)");
        return 0 ; // undefined ;
      }
    
    }
    
    var A = [] ;
      A[0] = 5
      A[1] = 1
      A[2] = 2
      A[3] = 7
      A[4] = 4
    console.log(solution(A)) ;
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Bergi    8 年前

    是的,在线性时间(甚至是常数空间)中用一个连续的和来完成这项工作是非常简单的。

    function solution(arr) {
        var leftSum = 0; // sum from 0 to P
        var rightSum = arr.reduce((a, b) => a + b, 0); // sum from P to N
        var min = Math.abs(leftSum - rightSum); // initial value for p=0
        for (var p = 0; p < arr.length; p++)
            // move the element from the right to the left side
            leftSum += arr[p];
            rightSum -= arr[p];
            // then update minimum difference
            min = Math.min(min, Math.abs(leftSum - rightSum));
        }
        return min;
    }