每日编程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;}
}
本来是想把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;}
}
相关文章推荐
- 【编程之美】寻找数组中的最大值和最小值
- 编程之美-求数组的子数组之和的最大值方法整理
- 程序员编程艺术:第七章、求连续子数组的最大和
- 【程序员编程艺术】第七章:最大连续子数组和
- 【编程习题★★★☆☆】寻找数组中元素间最大差值
- 数组的最大和第二大的编程
- Java编程数组中最大子矩阵简便解法实现代码
- 最大子数组 三种不同复杂度的算法
- 编程之美 寻找数组中的最大值和最小值
- 编程之美 求数组的子数组之和的最大值
- node js 下查找数组最大最小值 时间复杂度 1.5N 思路来自编程之美
- 每天一道LeetCode-----找到给定数组的连续子数组,使这个子数组的和最大,要求复杂度为O(n)
- 求一个整数数组中和最大的连续子数组,例如:[1, 2, -4, 4, 10, -3, 4, -5, 1]的最大连续子数组是[4, 10, -3, 4](需写明思路,并编程实现)
- 程序员编程艺术:第七章、求连续子数组的最大和
- 编程之美3:寻找数组中的最大值和最小值以及最大值和次大值
- 编程之美--寻找数组中的最大值和最小值
- 编程之美 - 寻找数组中的最大值和最小值
- 编程之美_子数组的最大乘积
- 【编程之美】2.15 子数组之和的最大值(二维)
- 重新开始战斗15-编程之美-求数组的子数组之和的最大值