@[TOC]java代码求解最大子段和问题
什么是最大子段和问题
给定一个数组(元素已知),元素由正整数,负整数两种元素组成,现在求该数组中从哪个位置到哪个位置对应元素所组成的子段和最大,这个子段和就叫做最大子段和。
分析问题(分治思想)
最大子段和不是在“前半段”(a[0] ~ a[mid])就是在“后半段”a[mid+1] ~ a[a,length-1],要么就是由“前半段部分元素和后半段部分元素连接起来a[i] ~ a[j]所构成(其中i(从mid ~ 0),j(从mid+1) ~ (a.length -1);”
就以数组a[] = {-1,3,2}为例
前半段从-1 ~3 后半段从2 ~ 2(也就是它本身) DSZ就指的是前半段和后半段所连接的“累加和最大的”子段和
之后我们可以判断这三个值的大小 从而得出当前数组的最大子段和
发现捷径
当数组长度为2时可以比较a,b,a+b三个数的大小 从而选出最大值即为最大子段和
当数组长度大于2时 需递归调用方法将数组划分为长度等于2的小数组,逐步得到所要求数组的最大子段和。
因为当将数组划分到长度等于2的时候对应的小长度数组的最大子段和可以轻松的求解出来,进而一步步向所求数组一步步靠拢进而得到最终的最大子段和。
if(mid == 0){
x = a[0];
y = a[1];
z = x + y;
if(x > y){
max = x;
}
else max = y;
if(max > z){
max = max;
}
else {max = z;}
return max;
}
定义一个DSZ方法,用于返回当前数组前半段和后半段连接所构成的“累加和最大的”子段和
public static int DSZ(int a[]){
int mid = (a.length-1)/2;
int H = a.length;
int i,j,max,x,y,z,L,D;
if(H%2 != 0){
L = mid+1;
D = mid ;
}
else {
L = mid +1;
D = mid +1;
}
int[] d = new int[L];
int[] e = new int[D];
for(max = 0,i = mid,j = 0;i >=0;i--,j++){
max += a[i];
d[j] = max;
}
for(max = 0,i = (mid+1),j = 0;i < a.length;i++,j++){
max += a[i];
e[j] = max;
}
x = mid - ZDS(d);
y = mid +ZDS(e)+1;
for(max = 0,i = x;i <= y;i++){
max += a[i];
}
return max;
}
定义ZDS(最大数)方法用于辅佐DSZ方法求出前半段和后半段“累加和最大”的子段和
public static int ZDS(int a[]){
int max,i,j = 0;
for(i = 0,max = 0;i < a.length;i++){
if(max < a[i]){
max = a[i];
}
}
for(i = 0;i < a.length;i++){
if(max == a[i]){
j = i;
}
}
return j;
}
排版方法
import java.util.Scanner;
public class ZDZD4{
public static void main(String[] args){
System.out.println("请输入数组元素并用逗号隔开:");
Scanner s1 = new Scanner(System.in);
String str = s1.next().toString();
String[] b = str.split(",");
int[] a = new int[b.length];
for(int j = 0;j < a.length;j++){
a[j] = Integer.parseInt(b[j]);
System.out.print(a[j]+" ");
}
System.out.println();
System.out.print("该数组的最大子段和为:"+ZDZD1(a));
}
public static int ZDZD1(int a[]){
int i,j,x,v,max,y = 0,z = 0,n = 0,m = 0,H,L,D,t,q;
int mid = (a.length-1) / 2;
int O = a.length;
if(O == 1){
return a[0];
}
else if(O%2 != 0){
L = mid+1;
D = mid ;
}
else{
L = mid +1;
D = mid +1;
}
int[] b = new int[L];
int[] c = new int[D];
if(mid == 0){
x = a[0];
y = a[1];
z = x + y;
if(x > y){
max = x;
}
else max = y;
if(max > z){
max = max;
}
else {max = z;}
return max;
}
else {
x = DSZ(a);
for(i = 0;i <= mid ;i++){
b[i] = a[i];
}
for(v = mid+1,j= 0;v < a.length;v++){
if(a[v] != 0){
c[j] = a[v];
j++;
}
}
n = ZDZD1(b);
m = ZDZD1(c);
if(n > m){
max = n;
}
else {max = m;}
if(max > x){
max = max;
}
else {max = x;}
return max;
}
}
public static int DSZ(int a[]){
int mid = (a.length-1)/2;
int H = a.length;
int i,j,max,x,y,z,L,D;
if(H%2 != 0){
L = mid+1;
D = mid ;
}
else {
L = mid +1;
D = mid +1;
}
int[] d = new int[L];
int[] e = new int[D];
for(max = 0,i = mid,j = 0;i >=0;i--,j++){
max += a[i];
d[j] = max;
}
for(max = 0,i = (mid+1),j = 0;i < a.length;i++,j++){
max += a[i];
e[j] = max;
}
x = mid - ZDS(d);
y = mid +ZDS(e)+1;
for(max = 0,i = x;i <= y;i++){
max += a[i];
}
return max;
}
public static int ZDS(int a[]){
int max,i,j = 0;
for(i = 0,max = 0;i < a.length;i++){
if(max < a[i]){
max = a[i];
}
}
for(i = 0;i < a.length;i++){
if(max == a[i]){
j = i;
}
}
return j;
}
}