zoukankan      html  css  js  c++  java
  • 分治——最大连续数组和

    问题描述:

    给一个整数数组,求其所有子数组中和最大的子数组在所给整数数组的的起始位置与终点;

    方法一:穷举每个子数组,时间复杂度为o(N2);

    方法三:时间复杂度为O(N); 请自行查阅书籍;

    方法二:

      采用分治思想:

        先将数组从中间(分割点)分成两部分(和最大子数组要么在其左边,要么在其右边,或者跨过分割点),先求出左边和最大的子数组,再求右边和最大的子数组,

        然后求经过中间分隔点的最大子数组和;

          如何求经过中间分隔点的最大子数组和:从分割点开始向左累加求和,找到其和最大的的位置与所求和的值,再从分割点开始向右累加求和,找到其和最大的的位置与所求和的值。

        

     1 #include<iostream>
     2 using namespace std; 
     3 struct sub{      //定义一个子数组起点,终点与其所有元素和
     4     int start;
     5     int end;
     6     
     7     int sum;
     8 };
     9 
    10 sub merge(sub sub1,int start,int end,int A[]) //
    11 {
    12     int leftSum=0,rightSum=0,leftPos=(start+end)/2,rightPos=(start+end)/2+1,leftMax=-10000,rightMax=-10000;
    13 
    14     for(int i=(start+end)/2;i>=start;i--)
    15     {
    16         leftSum+=A[i];    //求最大数组和的起点
    17         if(leftMax<leftSum)
    18         {
    19             leftPos=i;
    20             leftMax=leftSum;            
    21         }
    22     }
    23     
    24     for(int i=(start+end)/2;i<=end;i++)
    25     {
    26          rightSum+=A[i];
    27         if(rightMax<rightSum)   //求最大数组和的终点
    28         {
    29             rightPos=i;
    30             rightMax=rightSum;            
    31         }
    32     }
    33     
    34     if ( sub1.sum< (rightMax+leftMax) )
    35     {
    36          sub1.start=leftPos;
    37         sub1.end=rightPos;
    38         sub1.sum= (rightMax+leftMax);
    39     }    
    40     
    41     return sub1;
    42 }
    43 sub recursion(int start,int end,int A[])
    44 {
    45     sub sub1,sub2;
    46     
    47     if(start<end)
    48     {
    49         sub1=recursion(start,(start+end)/2,A);
    50         sub2=recursion((start+end)/2+1,end,A);    
    51         
    52         sub1=sub1.sum>sub2.sum?sub1:sub2;
    53         
    54         return merge(sub1,start,end,A);
    55     }
    56     
    57     sub1.start=sub1.end=start;
    58     sub1.sum=A[start];
    59     
    60     return sub1; 
    61 }
    62 int main()
    63 {
    64     int a[]={1,-5,9,8,-3,-6,11};
    65     
    66     sub sub1=recursion(0,6,a);
    67     
    68     cout<<sub1.start<<" to "<<sub1.end<<" sum:"<<sub1.sum<<endl; 
    69     
    70 }
    71  
  • 相关阅读:
    [转]HDR渲染器的实现(基于OpenGL)
    32位微机的内存管理模式
    王爽汇编检测点1.1
    标志位的说明
    通用寄存器的作用
    Debug初次使用
    昨天纠结了一天要始学习dos汇编还是win32汇编,终于想通了
    CPU对存储器的读写(二、数据总线、控制总线)
    CPU对存储器的读写(一、地址总线)
    段寄存器的引用
  • 原文地址:https://www.cnblogs.com/z-bear/p/7667814.html
Copyright © 2011-2022 走看看