java 求最大子序列和问题递归求解报越界异常
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 求最大子序列和问题递归求解报越界异常相关的知识,希望对你有一定的参考价值。
/** * 分治递归求解问题: * 分为三种情况: * 1.最大子序列出现在左半边部分 * 2.最大子序列出现在右半边部分 * 3.最大子序列出现在中间部分,此时取两边的最大子序列的和之和(左边子序列包含最后一个元素,右边子序列包含第一个元素) * * @param array * @return */ public static int maxSubSum1(int[] array) return maxSubSumRec(array,0,array.length-1); /** * 闭区间 */ private static int maxSubSumRec(int[] array, int left, int right) if(left==right) return array[left]>0?array[left]:0; int center = (left+right)/2; System.out.println(left+" "+center+" "+right); int maxLeft = maxSubSumRec(array,left,center); //左侧子串和最大值 int maxRight = maxSubSumRec(array,center+1,right); //右侧子串和最大值 //中间部分最大值 int maxLeftFromCenter = 0,maxRightFromCenter = 0; for(int i=center,currentSum = 0;i>=left;i--) currentSum+=array[i]; if(currentSum > maxLeftFromCenter) maxLeftFromCenter = currentSum; for(int i=center+1,currentSum = 0;i<=right;i++) currentSum+=array[i]; if(currentSum > maxLeftFromCenter) maxRightFromCenter = currentSum; int maxCenter = maxLeftFromCenter+maxRightFromCenter; return Math.max(Math.max(maxLeft, maxCenter),maxRight); 程序运行结果如下:
参考技术A 第二个测试用例中,空数组的长度为0return
maxSubSumRec(array,0,array.length-1);
这就导致这一步调用传入的实参为
return
maxSubSumRec(array,0,-1);
所以,导致数组越界。
分治法
分治法的思想:
分治法的思想是分开求解然后合并。分治法的思想在很多算法中都广泛使用,例如二分查找,归并排序,快速排序。
分治法的主要步骤;
1、 划分问题:把问题分为子问题。
2、 递归求解:递归解决问题。
3、 合并问题:合并子问题得到原问题的解。
典型例题:
给出一个数组n的序列A1,A2,------An,求最大连续和。
看到这里,我们不免想到了使用数组前缀和来求解,但在n足够大时,最坏的情况下,时间复杂度为O(n^2);可能会超时。但是使用分治法,时间复杂度为n*log2(n);
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=10010; int a[N]; int n,sum; int maxsum(int x,int y) { //printf("11 "); if(y-x==1) return a[x]; //只有一个元素直接返回 int v,L,R,maxs; int m=x+(y-x)/2; //划分区间为[x,m)和[m,y); maxs=max(maxsum(x,m),maxsum(m,y)) ;//递归求解 v=0;L=a[m-1]; for(int i=m-1;i>=x;i--) L=max(L,v+=a[i]); //合并(1)———从分界点到左的最大连续和 v=0;R=a[m]; for(int i=m;i<y;i++) R=max(R,v+=a[i]); //合并(2)———从分界点到右的最大连续和 return max(maxs,L+R); //把子问题的解与L和R比较 } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; cout<<maxsum(1,n+1)<<endl; return 0; }
以上是关于java 求最大子序列和问题递归求解报越界异常的主要内容,如果未能解决你的问题,请参考以下文章