将复杂度从O(n)改为O(1)

时间:2012-05-05 13:43:52

标签: algorithm complexity-theory

以下代码:

 s = 0 ;  
 for(i=m ; i<=(2*n-1) ; i+=m)  {  
      if(i<=n+1){ 
        s+=(i-1)/2 ; 
      }  
      else{ 
        s+=(2*n-i+1)/2 ; 
      }    
 }

我想从O(n)更改代码的复杂性 到O(1)。所以我想消除for循环。但是作为 总和s存储(i-1)/2(2*n-i+1)/2等值,因此消除循环涉及繁琐计算每个(i-1)/2(2*n-i+1)/2的最低值。我这样做变得非常困难,因为我可能在楼层总和中得出了错误的公式。你可以帮助我改变从O(n)O(1)的复杂性。或者请帮助我这个楼层总结。有没有其他方法可以降低复杂性?如果是的话......那怎么样?

2 个答案:

答案 0 :(得分:2)

我的方法是首先编写表征测试,断言为mn的不同值生成的值,然后开始重构。

你的主循环基于中途(if(i<=n+1)选择)的逻辑变化,所以我首先将它分成两个循环。

然后,在每个结果循环中,计算主要取决于i是偶数还是奇数。将每个分成两个分开的循环,并且可以更容易理解地板计算。或者,您可能会看到重复值的模式,使您可以以不同的方式简化这些循环。

每个结果循环可能类似于算术级数的总和,因此您可能会发现它们可以被封闭形式的计算所取代,而根本不需要循环。

当您沿着这条路走时,您也可能会重构以将部分计算提取到函数中。在提取它们时为它们写出特征化测试。

继续运行所有测试,你可能会将其减少到一个简单计算的总和,然后可以通过普通的算术进一步减少。

答案 1 :(得分:2)

Don Roby说,对你的问题有一个简单的算术解决方案。让我告诉你如何为i的第一个值做这件事。

*编辑2:较低部分的代码*

    for(int i=m ; i<= n+1 ; i+=m)//old computation
          s+=(i-1)/2 ;


    int a = (n+1)/m; // maximum value of i
    int b = (a*(a+1))/2; //
    int v = 0;
    int p;
    if(m % 2 == 0){
        p = m/2;
        v = b*p-a; // this term is always here
    }
    else{
        p = (m - 1)/2;
        int sum1 = ((a/2)*(a/2 +1))/2; 
        int sum2 =  (((a-1)/2)*((a-1)/2 +1))/2;  

        v = b*p -a ;// this term is always here
        v+= sum1 + a/2; //sum( 1 <= j <= a )(j-1), j pair
        v+= sum2; //sum( 1 <= j <= a )(j-1), j impair
    }
    System.out.println( " Are both result equals ? "+ (s == v));

我如何想出来?

 for(i=m ; i<= n+1 ; i+=m)
      s+=(i-1)/2 ;

我做了一个改变

 for(j=1 ; j*m <= n-1 ; j++)
     s+=(j*m-1)/2 ;

我摆出a=Math.floor(n+1/m)。有3例:

  1. m是对,然后循环的内部是s+= p*j。结果是

     b(a*(a+1))/2 -a
    
  2. m有损,迭代器j是对

  3. m受损并且迭代器j受损 当m受损时,你可以写m = 2p + 1并且循环内部变为

     s+= p*j + (j-1)/2
    
  4. p*j与之前相同,现在你需要通过假设j总是对或j总是损害并对两个值求和来打破除法。

    您需要计算的下一个循环是

     for(int i=a+1 ; i<= (2*n-1) ; i+=m)// a is (n+1)/m
        s+=(2*n-i+1)/2;
    

    相同
     for(int i=1 ; i<= (2*n-1)-a ; i+=m)
        s+= (2n-a)/2 - (i-1)/2;
    

    这个循环类似于第一个循环,因此没有太多工作要做...... 确实这很乏味......