• 分治法求最大子序列,关于复杂度的一次弱推导


       1:  #include <stdio.h>
       2:  #include <stdlib.h>
       3:   
       4:  int sc=0;
       5:  int max3(int a,int b, int c)
       6:  {
       7:      sc++;
       8:      if(a>b)
       9:      {
      10:          return a>c?a:c;
      11:      }
      12:      else
      13:      {
      14:          return b>c?b:c;
      15:      }
      16:  }
      17:   
      18:  int max_sub_sum(const int v[], int left, int right)
      19:  {
      20:      int center;
      21:      int maxLeftHalfSum;
      22:      int maxRightHalfSum;
      23:      int leftHalfWithRightBorderSum;
      24:      int rightHalfWithLeftBorderSum;
      25:      int maxLeftHalfWithRightBorderSum;
      26:      int maxRightHalfWithLeftBorderSum;
      27:      int i;
      28:   
      29:      if(left==right)
      30:      {
      31:          return v[left]>0?v[left]:0;
      32:      }
      33:      center=(left+right)/2;
      34:   
      35:      maxLeftHalfWithRightBorderSum=leftHalfWithRightBorderSum=
      36:      maxRightHalfWithLeftBorderSum=rightHalfWithLeftBorderSum=0;
      37:      for(i=center;i>=left;i--)
      38:      {
      39:          leftHalfWithRightBorderSum+=v[i];
      40:          if(leftHalfWithRightBorderSum>maxLeftHalfWithRightBorderSum)
      41:          {
      42:              maxLeftHalfWithRightBorderSum=leftHalfWithRightBorderSum;
      43:          }
      44:      }
      45:   
      46:      for(i=center+1;i<=right;i++)
      47:      {
      48:          rightHalfWithLeftBorderSum+=v[i];
      49:          if(rightHalfWithLeftBorderSum>maxRightHalfWithLeftBorderSum)
      50:          {
      51:              maxRightHalfWithLeftBorderSum=rightHalfWithLeftBorderSum;
      52:          }
      53:      }
      54:   
      55:      return max3(max_sub_sum(v,left,center),max_sub_sum(v,center+1,right),
      56:                  maxLeftHalfWithRightBorderSum+maxRightHalfWithLeftBorderSum);
      57:  }
      58:   
      59:  int main()
      60:  {
      61:      int v[]={1,-1,2,-2,5,-3,4,-4};
      62:      int r=max_sub_sum(v,0,7);
      63:      printf("the max sub sum is %d in step %d",r,sc);
      64:      return 0;
      65:  }

    sc 用来统计max3执行的次数,这其实也是递归函数调用的次数,不妨假设N为2的整数次幂运算,即N=2k ,很明显依分治思路sc=1+21+22+…=20+21+22+…2k-1=2k-1=N-1.

    通过简单推理可以知道sc其实就是把问题分治之后的所有子集的规模

    众所周知该算法的复杂度为O(NlogN),现在我们来看一下复杂度T(N)是怎麽求解出来的:

    T(N)=N*20 +(N/2k-1)*21+(N/2k-2)*22+…(N/2)2k-1 =(k-1)*N                    //注意此处推导,是基于sc的推到结果,复杂度近似等于求和sc的每一次递归调用产生的37~53步的循环次数,还不知道如何输入求和符号。。汗

    而k显然为logN,此处对数底为2,于是我们大致推导出算法的复杂度为N*(logN-1).

  • 相关阅读:
    Lucene综合案例
    Lucene 高级搜索
    Lucene 分词器
    Lucene 索引维护
    Lucene Field域类型
    Lucene入门
    Lucene介绍和全文检索流程
    数据查询方法
    序列化
    drf
  • 原文地址:https://www.cnblogs.com/dancewithautomation/p/2550146.html
Copyright © 2020-2023  润新知