每日学习---18.5.1

数据结构--算法最大子列和

最大子列和问题   取自Mooc 浙江大学数据结构课程

package 最大子列和问题;
import java.util.*;
public class MaxSubseqSum {
Scanner input = new Scanner(System.in);
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array[] = new int[9];
for (int i = 0; i < array.length; i++) {
array[i] = input.nextInt();
}
System.out.println();
Violence_algorithm(array);//暴力算法
/*
* 最基础的暴力枚举 时间复杂度为T(N)=O(N*N*N)
*/
/*简单一点的暴力算法T(N)=N(N*N)*/
Simple_less(array);
/* 分而治之 *///T(N)=O(Nlog(N));
System.out.println("最大子列和为"+DivideAndConquer(array, 0, array.length - 1));
//在线处理   时间复杂度为N(N)
Online_processing(array);
}


private static void Online_processing(int[] array) {
int sum=0,MaxSum=0;
int i;
sum=MaxSum=0;
for(i=0;i<array.length;i++) {
sum+=array[i];//向右累加
if(sum>MaxSum)
MaxSum=sum;
else if(sum<0)
sum=0;
}
System.out.println("最大子列和为"+MaxSum);
}


private static void Violence_algorithm(int[] array) {// 算法1 暴力算法
int sum = 0, Maxsum = 0;
int i, j, k;
for (i = 0; i < array.length; i++) {/* i是子列左端位置 */
for (j = i; j < array.length; j++) {/* j 是子列右端位置 */
sum = 0;
for (k = i; k <= j; k++) {/* k用来遍历 i 与 j 直接的数组元素 */
sum += array[k];/* k=j 容易忘记 */
if (sum > Maxsum) {
Maxsum = sum;
}


}
}
}
System.out.println("最大子列和" + Maxsum);
}


private static void Simple_less(int[] array) {
int sum = 0, Maxsum = 0;
int i, j;
for (i = 0; i < array.length; i++) {
sum = 0;//每一次不必从头开始加 只需要  从该循环的上一次最后结果sum +后一个数  
for (j = i; j < array.length; j++) {
sum += array[j];
if (sum > Maxsum) {
Maxsum = sum;
}
}
}
System.out.println("最大子列和" + Maxsum);
}


// 分治法
private static int DivideAndConquer(int List[], int left, int right) {
/* 分治法求List[left]到List[right]的最大子列和 */
int MaxLeftSum, MaxRightSum; /* 存放左右子问题的解 */
int MaxLeftBorderSum, MaxRightBorderSum; /* 存放跨分界线的结果 */


int LeftBorderSum, RightBorderSum;
int center, i;


if (left == right) { /* 递归的终止条件,子列只有1个数字 */
if (List[left] > 0)
return List[left];
else
return 0;
}


/* 下面是"分"的过程 */
center = (left + right) / 2; /* 找到中分点 */
/* 递归求得两边子列的最大和 */
MaxLeftSum = DivideAndConquer(List, left, center);
MaxRightSum = DivideAndConquer(List, center + 1, right);


/* 下面求跨分界线的最大子列和 */
MaxLeftBorderSum = 0;
LeftBorderSum = 0;
for (i = center; i >= left; i--) { /* 从中线向左扫描 */
LeftBorderSum += List[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
} /* 左边扫描结束 */


MaxRightBorderSum = 0;
RightBorderSum = 0;
for (i = center + 1; i <= right; i++) { /* 从中线向右扫描 */
RightBorderSum += List[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
} /* 右边扫描结束 */


/* 下面返回"治"的结果 */
return Math.max(Math.max(MaxLeftBorderSum, MaxRightBorderSum), MaxRightBorderSum + MaxLeftBorderSum);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值