最大连续子数组和
来源:互联网 发布:算法第四版课后题答案 编辑:程序博客网 时间:2024/05/18 18:54
题目描述
输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值,要求时间复杂度为O(n)。
例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5 ,和最大的子数组为 3, 10, -4, 7, 2 , 因此输出为该子数组的和18。
抛出Java代码,暴利扫描法O(n3) 和 正确解题法 O(n)
public class MaxSubArray {public static int getMaxSubArray(int[] arr ,int n){int maxSum = arr[0];int curSum = 0;for(int i = 0; i<n; i++){for(int j=i; j<n; j++){for(int k=i; k<=j; k++){curSum += arr[k];}if(curSum > maxSum){maxSum = curSum;}curSum = 0;}}return maxSum;}public static int getMaxSubArr(int[] arr,int n) {int curSum = 0;int maxSum = arr[0];for(int j=0; j<n; j++){curSum = (arr[j] > curSum + arr[j]) ? arr[j] : curSum + arr[j];maxSum = (maxSum > curSum) ? maxSum : curSum;}return maxSum;}public static void main(String[] args) {int[] array = new int[]{1,-2,3,10,-4,7,2,-5};int sum1 = getMaxSubArray(array,array.length);int sum = getMaxSubArr(array, array.length);System.out.println("最大子数组和:" + sum);}}
#include <iostream>using namespace std;int MaxSubArray(int array[],int len){ if(array==NULL || len<=0) return -1; int start=0,end=0; int curSum=0; int maxSum=array[0]; for(int i=0; i<len; i++) { if(curSum<0) //如果当前最大和为负数,则舍弃前面的负数最大和,从下一个数开始计算 { curSum=array[i]; start=i; } else curSum += array[i]; if(curSum>maxSum) { maxSum=curSum; end=i; } cout << "curSum:" << curSum << " maxSum:" << maxSum << endl; } cout<<"最大子序列位置:"<<start<<"--"<<end<<endl; return maxSum;}int main(){ int array[]={1,-2,3,10,-4,7,2,-5}; int len=sizeof(array)/sizeof(int); int maxsum=MaxSubArray(array,len); cout << "最大子序列和:" << maxsum << endl;}
下面给出《Data structures and Algorithm analysis in C》中4种实现。
//Algorithm 1:时间效率为O(n*n*n)int MaxSubsequenceSum1(const int A[],int N){int ThisSum=0 ,MaxSum=0,i,j,k;for(i=0;i<N;i++)for(j=i;j<N;j++){ThisSum=0;for(k=i;k<j;k++)ThisSum+=A[k];if(ThisSum>MaxSum)MaxSum=ThisSum;}return MaxSum;}//Algorithm 2:时间效率为O(n*n)int MaxSubsequenceSum2(const int A[],int N){int ThisSum=0,MaxSum=0,i,j,k;for(i=0;i<N;i++){ThisSum=0;for(j=i;j<N;j++){ThisSum+=A[j];if(ThisSum>MaxSum)MaxSum=ThisSum;}}return MaxSum;}//Algorithm 3:时间效率为O(n*log n)//算法3的主要思想:采用二分策略,将序列分成左右两份。//那么最长子序列有三种可能出现的情况,即//【1】只出现在左部分.//【2】只出现在右部分。//【3】出现在中间,同时涉及到左右两部分。//分情况讨论之。static int MaxSubSum(const int A[],int Left,int Right){int MaxLeftSum,MaxRightSum; //左、右部分最大连续子序列值。对应情况【1】、【2】int MaxLeftBorderSum,MaxRightBorderSum; //从中间分别到左右两侧的最大连续子序列值,对应case【3】。int LeftBorderSum,RightBorderSum;int Center,i;if(Left == Right)Base Caseif(A[Left]>0)return A[Left];elsereturn 0;Center=(Left+Right)/2;MaxLeftSum=MaxSubSum(A,Left,Center);MaxRightSum=MaxSubSum(A,Center+1,Right);MaxLeftBorderSum=0;LeftBorderSum=0;for(i=Center;i>=Left;i--){LeftBorderSum+=A[i];if(LeftBorderSum>MaxLeftBorderSum)MaxLeftBorderSum=LeftBorderSum;}MaxRightBorderSum=0;RightBorderSum=0;for(i=Center+1;i<=Right;i++){RightBorderSum+=A[i];if(RightBorderSum>MaxRightBorderSum)MaxRightBorderSum=RightBorderSum;}int max1=MaxLeftSum>MaxRightSum?MaxLeftSum:MaxRightSum;int max2=MaxLeftBorderSum+MaxRightBorderSum;return max1>max2?max1:max2;}//Algorithm 4:时间效率为O(n)//同上述第一节中的思路3、和4。int MaxSubsequenceSum(const int A[],int N){int ThisSum,MaxSum,j;ThisSum=MaxSum=0;for(j=0;j<N;j++){ThisSum+=A[j];if(ThisSum>MaxSum)MaxSum=ThisSum;else if(ThisSum<0)ThisSum=0;}return MaxSum;}
参考:
http://blog.csdn.net/v_JULY_v/article/details/6444021
http://www.cnblogs.com/xwdreamer/archive/2012/05/04/2482507.html
0 0
- 连续子数组最大和
- 连续最大子数组和
- 连续子数组最大和
- 最大连续子数组和
- 连续子数组最大和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和。
- 最大子数组和(连续)
- 最大连续子数组和
- 最大连续子数组和
- 最大连续子数组和
- linux中防DDOS攻击软件DDoS-Deflate详解
- java IO操作学习
- java BufferedReader类的子类-LineNumberReader类
- Laplacian Matrix
- 如何找出单链表中的倒数第k个元素
- 最大连续子数组和
- 七种寻址方式(立即寻址、寄存器寻址)
- Android屏幕适配相关知识
- 设计模式之二---观察者设计模式
- 从内存DC中保存成叠加的bmp文件
- hdu1877 又一版 A+B (栈)
- A Beginner's Guide To LVM [2/9]
- apache flume agent安装
- 【BZOJ3875】[Ahoi2014]骑士游戏【最短路】【DP】