zoukankan      html  css  js  c++  java
  • 算法笔记1-最大子序列和问题的求解

    问题——

    给定N个整数(有可能是负数)A1,A2,A3,A4...An,求最大子序列和。

    (子序列必须是连续的);比方,对于输入,-2,11-4,13-5-2。这个序列,

    答案是20,即从A2A4

     

    对于这个问题,你怎么想的呢?以下有四种解法,看看你的解法是不是当中之中的一个。

    解法一、穷举

    解题思路——

    既然是求某一个连续的子序列的最大和,那么我们把全部的子序列的和都加一遍。然后用一个变量来存储最大的和值。当遍历一遍全部子序列,就可以得到最大的和。

    因为这个子序列长度能够是1。也能够是N。因此须要三重循环。

    详细程序——

     private static int calOne(int[] list){
        	int maxSum = 0;
        	for (int i = 0; i < list.length; i++) {
    	for (int j = i; j < list.length; j++) {
    		int thisSum = 0;
    		for (int k = i; k < j; k++) {
    			thisSum += list[k];
    		}
    		if (thisSum > maxSum) {
    			maxSum = thisSum;
    		}
    	}
    	}
        	return maxSum;
        }
    



    測试——

    为了測试其性能。构建大量数据比較耗费时间。所以这里我让它反复计算某一个数组1万次。

     

       public static void main(String[] args)  {    
           int[] test = {-2,11,-4,13,-5,-219,23,234,-190,280,-20,1340,123,-324,43,-35};
           long time = System.currentTimeMillis();
           for (int i = 0; i < 9999; i++) {
        	   calOne(test);
    	}
            System.out.println(calOne(test));
            System.out.println("算法1所用时间:"+(System.currentTimeMillis()-time)+"毫秒");
    
        }   

        

    结果是:

    1790

    算法1所用时间:22毫秒

    明显,三重循环,其执行时间是O(N^3)

     

    解法二、改进的穷举

    通过观察。我们发现。事实上第三重循环是不必要的,由于第二次循环已经计算了第三次循环的数值。因此能够撤销。

     

    private static int calTwo(int[] list) {
    	int maxSum = 0;
    	for (int i = 0; i < list.length; i++) {
    	int thisSum = 0;
    	for (int j = i; j < list.length; j++) {
    		thisSum += list[j];
    
    	if (thisSum > maxSum) {
    		maxSum = thisSum;
    	}
    	}
    	}
    	return maxSum;
    	}
    


    撤销后的时间复制度是ON^2,我们来看执行时间。

    1790

    算法2所用时间:6毫秒

     确实降低了不少时间,可是这还是非常差劲的穷举算法。须要改进。

     

    解法三、联机算法

    联机算法优缺点——

    在随意时刻,算法对要操作的数据仅仅读入(扫描)一次,一旦被读入并处理。它就不须要在被记忆了。

    而在此处理过程中算法能对它已经读入的数据马上给出对应子序列问题的正确答案。具有这样的特性的算法叫做联机算法(on-line algorithm)。

    该算法仅须要常量空间并以线性时间执行。因此联机算法差点儿是完美的算法。

    长处:占用空间少。所用时间少

    缺点:不宜设计。正确性不易观察。同一时候附加保留信息较少

     

    详细程序——

    private static int calThree(int[] list) {
    	int maxSum = 0,thisSum = 0;;
    		 
    		for (int j = 0; j < list.length; j++) {
    			
    			thisSum += list[j];
    
    	if (thisSum > maxSum) {
    		maxSum = thisSum;
    	}else if(thisSum <0){
    		thisSum = 0;
    	}
    	}
    	return maxSum;
    	}
    


     

    能够看到,联机算法的时间复杂度是O(N),节省了非常多时间。

    执行验证下。

    相同地计算一组数据1万次,结果是——

    1790

    算法3所用时间:2毫秒

     

    关于这个问题。另一种分治策略的算法。尽管不如联机算法。可是比起差劲的穷举,还是改进不少的。

    以上是个人的读书笔记,书籍为《数据结构与算法描写叙述》。

    欢迎探讨。

     

  • 相关阅读:
    学习进度总结表
    关于软件工程的问题
    自我介绍
    web安全
    spring profile
    spring 装配
    python Descriptor (描述符)
    python string intern
    Java 对象内存占用
    java jdb命令详解
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5101388.html
Copyright © 2011-2022 走看看