码迷,mamicode.com
首页 > 编程语言 > 详细

最大子数组问题

时间:2020-02-18 16:35:21      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:key   find   body   因此   中间   分解   算法   function   lin   

问题描述

算法导论P38提到
来源:已知一股票在某一段时间内的变化趋势,问该时间段内何时买入,何时卖出,使得收益最大,求出最大值
转化:给定一个数组,从中选取一个连续的子数组,使得其元素和在所有的子数组中最大,返回该最大值。

解决方案

暴力搜索

n个元素中选取两个元素,计算两个元素之间的元素的和,将其与max相比,如果比max大,则替换;
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static int (int []a){
int max=0;
int sum=0;
for(int i=0;i<a.length;i++){
for(int j=i;j<a.length;j++){
for(int k=i;k<=j;k++){
sum+=a[k];
}
if(sum>max){
max=sum;
}
sum=0;
}
}
return max;
}

分治策略

把一个数组从中分开为两个子数组,最大子数组可能的情况是:在左边的子数组,在右边的子数组,含左边的一部分和右边的一部分;对于前两种情况只是将原问题分解为较小的原问题,而第三种情况既然包括左边和右边,一定含有中间的元素,因此很好解决,从左从右遍历即可;然后将这三种情况进行比较,选取最大的部分返回
这个问题和归并排序是一个道理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//采用分治策略,时间复杂度为O(nlgn)
public static int getMaxSum2(int []a){
return findMaxSub(a,0,a.length-1);
}
public static 大专栏  最大子数组问题">int findMaxSub(int[] a,int left,int right){
if(left==right) return a[left];
int mid=left+(right-left)/2;
int leftSum=findMaxSub(a, left, mid);
int midSum=findMaxCro(a, left,mid, right);
int rightSum=findMaxSub(a, mid+1, right);
if(leftSum>midSum&&left>rightSum) return leftSum;
if(rightSum>leftSum&&rightSum>midSum) return rightSum;
return midSum;
}
public static int findMaxCro(int[] a,int left,int mid,int right){
int maxleft,maxright;
int sum=0;
maxleft=a[mid];
for(int i=mid;i>=left;i--){
sum+=a[i];
if(sum>maxleft){
maxleft=sum;
}
}
maxright=0;
sum=0;
for(int i=mid+1;i<=right;i++){
sum+=a[i];
if(sum>maxright){
maxright=sum;
}
}
return maxleft+maxright;
}

DP解法

第sum[i-1]个元素是前i-1个元素的最大子数组的和,如果sum[i-1]小于0,则sum[i]=a[i],否则sum[i]=sum[i-1]+a[i];最后的结果result取sum[i]的最大值
sum[i]=max(a[i],sum[i-1]+a[i])
result=max(result,sum[i])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//时间复杂度为O(n)
public static int getMaxSum3(int []a){
int b=0;
int sum=0;
for(int i=0;i<a.length;i++){
if(b>=0){
b+=a[i];
}else{
b=a[i];
}
if(b>sum){
sum=b;
}
}
return sum;
}

参考:
http://blog.csdn.net/v_JULY_v/article/details/6444021

最大子数组问题

标签:key   find   body   因此   中间   分解   算法   function   lin   

原文地址:https://www.cnblogs.com/lijianming180/p/12326557.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!