zoukankan      html  css  js  c++  java
  • 每日一记,今天开始

    从今天开始每天争取自己手写一两个小程序,即使是从书上看的,或者从网上学的,都自己手动地把代码打出来,贴在这里。

    培养自己这个习惯,尽最大可能坚持下来。

    水滴石穿,绳锯木断。

    2014年9月10日

    今天学习的是:求最大子序列和

    有三种算法:

    1 复杂度为O(N2)

     1 package findmaxsub;
     2 
     3 //求最大子序列和算法1:相当是遍历了一遍
     4 
     5 public class FindMaxSu {
     6 
     7     public static void main(String[] args) {
     8         // TODO Auto-generated method stub
     9         int[] a = new int[] {4,-3,5,-2,-1,2,6,-2,10};
    10         System.out.println(findMax(a));
    11 
    12     }
    13     private static int findMax(int [] array){
    14         int maxSum = 0;
    15         for(int i=0;i<array.length;i++){
    16             int sum=0;
    17             for(int j=i;j<array.length;j++){
    18                 sum+=array[j];
    19                 if(sum>maxSum){//注意这个if的位置
    20                     maxSum=sum;
    21                 }
    22             }    
    23         }
    24         return maxSum;
    25     }
    26 }

    2 复杂度为O(NlogN)

     1 package findmaxsub;
     2 
     3 //寻找最大子序列和的算法2
     4 //基本思路:最大子序列和三种情况:出现在数据的左半部分,右半部分,跨越数据的中部从而位于左右两半部分之中
     5 //前两种情况用递归,后一种情况简单地用两个for循环就行了
     6 
     7 //分而治之的思想:divide-and-conquer
     8 //递归的思想
     9 //关键是处理第三种情况为什么能用两个简单的循环:因为子序列的头已经确定了,必须包含这个中间的元素
    10 
    11 public class FindMaxSub {
    12 
    13     /**
    14      * @param args
    15      */
    16     public static void main(String[] args) {
    17         // TODO Auto-generated method stub
    18         
    19         int[] arr = new int[]{4,-3,5,-2,-1,2,6,-2,10};
    20         System.out.println(maxSub(arr,0,arr.length-1));
    21     
    22 
    23     }
    24     
    25     private static int maxSub(int [] array,int left,int right){
    26         if(left==right){
    27             if (array[left]>0)
    28                return array[left];
    29             else
    30                return 0;
    31         }
    32         int center= (left+right)/2;
    33         //前两种情况用递归
    34         int leftMax=maxSub(array,left,center);
    35         int rightMax=maxSub(array,center+1,right);
    36         
    37         //后一种情况用两个for循环
    38         int leftBorderMax=0; int leftBorderSum=0;
    39         for(int i=center;i>=left;i--){
    40             leftBorderSum+=array[i];
    41             if(leftBorderSum>leftBorderMax){
    42                 leftBorderMax=leftBorderSum;
    43             }
    44         }
    45         int rightBorderMax=0; int rightBorderSum=0;
    46         for(int i=center+1;i<=right;i++){
    47             rightBorderSum+=array[i];
    48             if(rightBorderSum>rightBorderMax){
    49                 rightBorderMax=rightBorderSum;
    50             }
    51         }
    52         
    53         return max3(leftMax,rightMax,leftBorderMax+rightBorderMax);
    54         
    55     }
    56     
    57     private static int max3(int a, int b, int c){
    58         int n=a>b?a:b;
    59         return c>n?c:n;
    60     }
    61 
    62 }

    3 复杂度为O(N)

     1 package findmaxsub;
     2 //求最大子序列和算法3:
     3 //这个算法最巧妙,时间运行最小
     4 //基于的思想:任何最大子序列的起点项不可能为负数,那么任何负的子序列不可能是最大子序列的前缀
     5 //所以只要前面的累积和为负数了,就可以重新选择开头了
     6 
     7 public class findMaxSubb {
     8 
     9     /**
    10      * @param args
    11      */
    12     public static void main(String[] args) {
    13         // TODO Auto-generated method stub
    14         int [] arr = new int[]{4,-3,5,-2,-1,2,6,-2};
    15         System.out.println(findMax(arr));
    16 
    17     }
    18     private static int findMax(int[] arr){
    19         int sum=0,maxSum=0;
    20         for(int i=0;i<arr.length;i++){
    21             sum+=arr[i];
    22             if(sum<0)
    23                 sum=0;
    24             if(sum>maxSum){
    25                 maxSum=sum;
    26             }
    27         }
    28         return maxSum;
    29     }
    30 
    31 }
  • 相关阅读:
    2190 ACM 数学概率论的乘法和加法原则
    2186 ACM 水题 int 向下取整
    2110 ACM Crisis of HDU 母函数
    2079 ACM 选课时间 背包 或 母函数
    2111 ACM 贪心 水题
    2108 ACM 向量积 凹凸
    My Web Developer Roadmap
    2109 ACM 排序
    2107 ACM 水题
    vi的常用命令
  • 原文地址:https://www.cnblogs.com/ivywenyuan/p/3965073.html
Copyright © 2011-2022 走看看