您的位置:首页 > 编程语言

每日编程28之求最大子数组(o(N)复杂度)

2013-04-11 13:29 211 查看
之前研究算法,还剩下三大难题——KMP,rb-tree和DP。。

本来是想把DP这一遗留问题解决,就看到了这个问题,后面才发现这个问题其实很简单,完全用不到动态规划的思想,或者是最简单的一维DP。

问题描述,

一个数组,n个元素,有正有负

求最大子数组,要求o(N)复杂度

例如,输入数组为 1,-2,3,10,-4,7,2,-5 则和最大的子数组为3,10,-4,7,2

解决方案

对数组进行一次遍历,在遍历的过程中记录一些信息,并不断的更新这一信息。包括

目前最大子数组的起始位置,结束位置,子数组和

当前正在遍历的子数组起始位置,当前位置,当前的和。。

若遍历到数组的某一元素,当前和为负,则丢弃当前子数组,从下一个元素开始重新计算

若当前遍历元素<0,则尝试比较当前子数组与历史最大子数组,决定是否进行更新

在数组遍历结束后,比较当前子数组与历史最大子数组,决定最后的结果输出。

核心代码如下,

int max_sub_array(int a[],int N,int &left,int &right,int &max)
//初始时,left=right=max=0

{

int cur_left = -1;

int cur_right = cur_max =0;

int index;

for(index =0;index <N;index++)

{

if(a[index] <0)

{

if(cur_max < 0)
{cur_left = index; cur_max =0; continue;}

if(cur_max > max)
{max = cur_max; left = cur_left+1;
right = cur_right; }

}

cur_right = index;

cur_max +=a[index];

}

}

上面这些代码的逻辑有点问题。。

正确的代码如下,

int max_sub_array(int a[],int N,int &left,int &right,int &max)

{

int cur_left =-1;

int cur_right =0;

int cur_max =0;

int index;

for(index =0;index <N;index++)

{

if(a[index]<0)

{

if(cur_max > max) {max = cur_max; left = cur_left +1;right = cur_right;}

cur_right = index;

cur_max += a[index];

if(cur_max <0) {cur_left = index; cur_max =0;}

continue;

}

cur_right = index;

cur_max += a[index];

}

if(cur_max > max) {max = cur_max; left = cur_left +1;right = cur_right;}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: