求最大子数组的和,以及求该最大子数组的起始位置和末尾位置
2014-05-08 22:04
399 查看
问题描述:
一个数组,长度为N,数组元素有负有正,如{-1, 4, 6, -3, 7, -3, -3, 9};我们可以清楚的知道最大的子数组应该是4到9,也就是下标1到下标7,和为17。求解思路:
第一种方法:我们可以用定义1、两个数ThisSum和MaxSum来记录当前数组的和,以及数组的最大和。2、我们可以用两个for循环来来遍历数组,每一次求出子数组的最大和,每个子数组从0开始,下一次遍历子数组就是从1开始,以此类推。如第一次就【0~N-1】的最大和,第二次就是【1~N-1】,第三次就是【2~N】。。。。
3、这样,每次用ThisSum来记录当前数组的和,MAXSum来记录当前子数组的最大和,与ThisSum比较,取其最大就能求出最大子数组的和。
4、还是看代码吧,这样比较好理解:
int MaxSubArraySum(int a[], int N, int &start, int &end) { int ThisSum, MaxSum, i, j; *start = 0; *end = 0; MaxSum = 0; for (i = 0; i < N; ++i) { ThisSum = 0; for (j = i; j < N; ++j) { ThisSum += a[j]; if (ThisSum > MaxSum) { *start = i; *end = j; MaxSum = ThisSum; } } } return MaxSum; }5、此方法的时间复杂度很明显为(O(N^2))
第二种算法:
思路:我们力求一种逼格最高的方法使得时间复杂度为(O(N)).
1、同样我们ThisSum来记录当前子数组的和,MaxSum来记录当前子数组最大和,我们可以从0位置开始便来,开始遍历每次ThisSum 加上 a[ i ],如果当前ThisSum大于MaxSum的话,将ThisSum的值付给MaxSum,如果当前的ThisSum<0的话就把ThisSum的值赋值为0,接着下一步的遍历。
2、这里我必须说一下,求最大子数组的起点到尾端的求法,
a、我们定义start 和end来记录
b、当thisSum > maxSum时记录end 等于此时的下标。
c、当thisSum < 0时,我们可以知道起点必须从新修改,改为下一个下标(i +1)为起点start,但是要小心下一个下标(i+1)可能
元素的值小于0,或者越界,所以我们必须判断一下。如:
if(i <= arr.length - 2 && arr[i+1] > 0){
start = i + 1;
}
我们可以写出代码:
int maxSubArraySum(int[] arr, int N, int &start, int end) { int maxSum = 0; int thisSum = 0; int i; *start = 0; *end = 0; for (i = 0; i < N; i++) { thisSum += arr[i]; if (thisSum > maxSum){ maxSum = thisSum; *end = i; } if (thisSum < 0){ thisSum = 0; if(i <= N - 2 && arr[i+1] > 0){ *start = i + 1; } } } //如果最大子数组不在数组里面的话(数组元素全部<=0),start,end赋值为-1 if(*start == 0 && *end == 0 && arr[0] <= 0){ *start = -1; *end = -1; } return maxSum; }
时间复杂度为(O(N))逼格满满有木有=_=
最后一点总结:
在《数据结构与算法分析:C语言描述》中的第二章就出现这一道题,作者从(O(N^3))一路杀到(O(N)),不得不佩服啊,有用循环和递归都有,今天我只讲两种比较典型的方法。还有的就是作者没有求出子数组的起点以及末端,我就装逼求了一下,哈哈。
相关文章推荐
- 查看端口占用情况(解除占用)
- C++ int转string 和 string转int 函数
- 回溯算法解八皇后
- php学习笔记——错误异常处理及路径问题
- Careercup - Google面试题 - 4847954317803520
- 两个公式
- leetcode 3Sum Closest
- Opencore and OMX core/component interaction (二)
- rails Redirect
- 解决Struts2上传文件到tomcat,重启tomcat后 ,文件自动被删除。
- HTML5+CSS3+JS(第二课).HTML5保留的常用元素(三)和新通用属性
- ubuntu下java配置环境变量出现错误的原因?待解决
- HA集群之Heartbeat浅析及heartbeat+haresource 推荐
- 简单记录控件事件的分发机制
- 2014年实习生招聘之多益网络实习生招聘笔试题—2014/04/17
- php中上传图片
- FPGA之阻塞赋值与非阻塞赋值
- java 泛型类型擦除
- maven命令
- Capture network packet and send rst packet to cut connection