zoukankan      html  css  js  c++  java
  • “最大子序列和”算法 java

    maxSubSum各自是最大子序列和的4中java算法实现。

    第一种算法执行时间为O(N^3),另外一种算法执行时间为O(N^2),第三种算法执行时间为O(nlogn),第四种算法执行时间为线性N


    public class Test {
    	public static void main(String[] args) {
    		int[] a = {-2, 11, -4, 13, -5, -2};//最大子序列和为20
    		int[] b = {-6, 2, 4, -7, 5, 3, 2, -1, 6, -9, 10, -2};//最大子序列和为16
    		System.out.println(maxSubSum4(a));
    		System.out.println(maxSubSum4(b));
    	}
    	//最大子序列求和算法一
    	public static int maxSubSum1(int[] a){
    		
    		int maxSum = 0;
    		
    		//从第i个開始找最大子序列和
    		for(int i = 0; i < a.length; i++) {
    			
    			//找第i到j的最大子序列和
    			for(int j = i; j<a.length; j++) {
    				
    				int thisSum = 0;
    				
    				//计算从第i个開始,到第j个的和thisSum
    				for(int k = i; k<=j; k++){
    					thisSum += a[k];
    				}
    				//假设第i到第j个的和小于thisSum。则将thisSum赋值给maxSum
    				if(thisSum>maxSum) {
    					maxSum = thisSum;
    				}
    			}
    		}
    		return maxSum;
    	}
    	
    	public static int maxSubSum2(int[] a) {
    		int maxSum = 0;
    		for(int i = 0; i < a.length; i++) {
    			//将sumMax放在for循环外面。避免j的变化引起i到j的和sumMax要用for循环又一次计算
    			int sumMax = 0;
    			for(int j = i; j < a.length; j++) {
    				sumMax += a[j];
    				if(sumMax>maxSum) {
    					maxSum = sumMax;
    				}
    			}
    		}
    		return maxSum;
    	}
    	
    	//递归,分治策略
    	//2分logn,for循环n,固O(nlogn)
    	public static int maxSubSum3(int[] a) {
    		return maxSumRec(a, 0, a.length - 1);
    	}
    	public static int maxSumRec(int[] a, int left, int right) {
    		//递归中的基本情况
    		if(left == right) {
    			if(a[left] > 0) return a[left];
    			else return 0;
    		} 
    		int center = (left + right) / 2;
    		//最大子序列在左側
    		int maxLeftSum = maxSumRec(a, left, center);
    		//最大子序列在右側
    		int maxRightSum = maxSumRec(a, center+1, right);
    		//最大子序列在中间(左边靠近中间的最大子序列+右边靠近中间的最大子序列)
    		int maxLeftBorderSum = 0, leftBorderSum = 0;
    		for(int i = center; i>=left; i--) {
    			leftBorderSum += a[i];
    			if(leftBorderSum > maxLeftBorderSum) maxLeftBorderSum = leftBorderSum;
    		}
    		int maxRightBorderSum = 0, rightBorderSum = 0;
    		for(int i = center+1; i<= right; i++) {
    			rightBorderSum += a[i];
    			if(rightBorderSum > maxRightBorderSum) maxRightBorderSum = rightBorderSum;
    		}
    		//返回最大子序列在左側,在右側。在中间求出的值中的最大的
    		return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
    	}
    	public static int max3(int a, int b, int c) {
    		return a > b?

    (a>c?a:c):(b>c?

    b:c); } //不论什么a[i]为负时,均不可能作为最大子序列前缀;不论什么负的子序列不可能是最有子序列的前缀 public static int maxSubSum4 (int [] a) { int maxSum = 0, thisSum = 0; for(int j = 0; j < a.length; j++) { thisSum += a[j]; if(thisSum>maxSum) maxSum = thisSum; else if (thisSum < 0) thisSum = 0; } return maxSum; } }



  • 相关阅读:
    [转]Spring的IOC原理[通俗解释一下]
    自我介绍
    什么是存储过程
    Linux 之 最常用的20条命令
    [转]sql语句中出现笛卡尔乘积 SQL查询入门篇
    mysql 多表连接
    正则表达式
    postman 测试API
    [转]mysql 视图
    数据库 修改统一显示时间
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7338964.html
Copyright © 2011-2022 走看看