• 最大子序列和问题的几种算法


    直接贴代码了:

    package data.structure.chapter2;

    import java.util.Date;
    import java.util.Random;

    public class MaxSequenceSumTest {

    /**
    * @param args
    */
    public static void main(String[] args) {
    int [] array=new int[10000000];
    Random r=new Random(100);
    for(int i=0;i<array.length;i++){
    int k=r.nextInt(20);
    if(k%2==0)
    array[i]=0-k;
    else
    array[i]=k;
    // System.out.print(array[i]+" ");
    }
    // System.out.println();
    // maxSum1(array);
    // maxSum2(array);
    // maxSum3(array);
    long start=System.currentTimeMillis();
    int sum=maxSum4(array,0,array.length-1);
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");

    maxSum5(array);
    }

    /**
    * f(n)=f(n-1)+f(n-2)
    * f(n)=1 n<=1
    */
    public static void f(int n){
    long [] array=new long[n+1];
    array[0]=1;
    array[1]=1;
    array[2]=2;
    for(int i=3;i<n+1;i++){
    array[i]=array[i-1]+array[i-2];
    }
    for(int i=0;i<n+1;i++){
    System.out.println("i="+i+"---------- "+array[i]);
    }
    }

    public static int maxSum1(int [] array){
    long start=System.currentTimeMillis();
    int sum=0;
    for(int i=0;i<array.length;i++){
    for(int j=i+1;j<array.length;j++){
    int s=array[i];
    for(int k=i+1;k<=j;k++){
    s=s+array[k];
    }
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }

    /**
    * 时间减半而已
    * @param array
    * @return
    */
    public static int maxSum2(int [] array){
    int sum=0;
    long start=System.currentTimeMillis();
    for(int i=0;i<array.length;i++){
    for(int j=i+1;j<array.length;j++){
    if(array[i]<0)
    break;
    int s=array[i];
    for(int k=i+1;k<=j;k++){
    s=s+array[k];
    }
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }

    /**
    * 少一重循环
    * @param array
    * @return
    */
    public static int maxSum3(int [] array){
    long start=System.currentTimeMillis();
    int sum=0;
    for(int i=0;i<array.length;i++){
    int s=array[i];
    for(int j=i+1;j<array.length;j++){
    s=s+array[j];
    if(s>sum) sum=s;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+sum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return sum;
    }


    /**
    * O(NlogN)时间复杂度
    * 分治策略:
    * 分:把问题分成两个大致相等的子问题,然后递归地对他们求解
    * 治:将两个子问题的解修补到一起并可能再做些少量的附加工作,最后得到整个问题的解
    * @param array
    * @param left
    * @param right
    * @return
    */
    public static int maxSum4(int [] array,int left,int right){
    if (left == right)
    if (array[left] > 0)
    return array[left];
    else
    return 0;
    int middle=(left+right)/2;
    int lMax=maxSum4(array,left,middle);
    int rMax=maxSum4(array,middle+1,right);
    int a=0;
    int aMax=0;
    for(int i=middle;i>=left;i--){
    a=a+array[i];
    if(a>aMax)
    aMax=a;
    }
    int b=0;
    int bMax=0;
    for(int i=middle+1;i<right;i++){
    b=b+array[i];
    if(b>bMax)
    bMax=b;
    }
    return Math.max(Math.max(lMax, rMax),aMax+bMax);
    }

    /**
    * 如果a[i]小于零,那么它不可能代表最优序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过
    * 用a[i+1]作为起点而得到改进。同理,任何小于零的子序列不可能是最优子序列的前缀。
    * @param array
    * @return
    */
    public static int maxSum5(int []array){
    long start=System.currentTimeMillis();
    int maxSum=0,thisSum=0;
    for(int i=0;i<array.length;i++){
    thisSum=thisSum+array[i];
    if(thisSum>maxSum){
    maxSum=thisSum;
    }else if(thisSum<0){
    thisSum=0;
    }
    }
    long end=System.currentTimeMillis();
    System.out.print("最大子序列的和为:"+maxSum+"--------花费时间:");
    System.out.println((end-start)/1000+"秒"+(end-start)%1000+"毫秒");
    return maxSum;
    }

    }

  • 相关阅读:
    php 本地 备份远程mysql和mdb 多任务只执行一次
    c# 监控服务器上传木马(包含可疑文件)
    jquery 简短 右键菜单 兼容ie6 ie7 ie8 firefox chrome
    分解从身份证中读回的户籍地址
    备份mysql(一表一文件)
    THINKPHP 3.0 整合KINDEDITOR 4.05
    c# 仿照计划任务(定时提示、定时运行程序、定时打开url(前台/后台))/每天/每周/每月/一次 多时间段
    php基本操作echo
    c# 扫描可疑文件(找到木马)(简)
    GOOGLE 地图,查询地名,移动标记,生成静态地图
  • 原文地址:https://www.cnblogs.com/yshb/p/2556965.html
Copyright © 2020-2023  润新知