第2章 算法分析


典型的增长率 
c   logN   log2N   N   NlogN   N2   N3   2N 


递归过程调用的一般形式是传递输入的数组以及左边界和右边界,它们界定了数组要被处理的部分。单行驱动程序通过传递数组以及边界0和N – 1而将该过程启动。 


对数最常出现的规律可概括为下列一般法则:如果一个算法用常数事件(O(1))将问题的大小削减为其一部分(通常是1/2),那么该算法就是O(logN)。另一方面,如果使用常熟事件只是把问题减少一个常数的数量(如将问题减少1),那么这种算法就是O(N)的。 




    
    /**
     * //子序列通杀<br>
     * 假设最优子序列是从i开始的,那么从i开始进行运算,求出的最优值一定是最优子序列的值
     * @param a
     * @return
     */
    private static void max(int[] a){
        int maxSum = 0;
        boolean maxfirst = true;
        int thisSum = 0;
        boolean thisfirst = true;
        for(int i = 0;i<a.length;i++){
            thisSum = 0;
            for(int j=i;j<a.length;j++){
                if(thisfirst){
                    thisSum = a[i];
                    thisfirst = false;
                }else {
//                 thisSum += a[j];//和
                    thisSum *= a[j];//乘积
                }
                if(thisSum > maxSum){//求最大子序列 
//                if(thisSum < maxSum){//求最小子序列 
//                 if(thisSum>0&&thisSum < maxSum){//求最小正子序列
//                if(maxfirst&&thisSum<0){//求最大负子序列
                    maxSum = thisSum;
                    maxfirst = false;
                }else if(thisSum>0&&thisSum > maxSum){//求最大子序列乘
//                }else if(thisSum<0&&thisSum > maxSum){//求最大负子序列
                    maxSum = thisSum;
                }
            }
        }
       System.out.println("最优值为:" + maxSum);
    }
    //分治
    private 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;
            }
        }
        int k = maxRightBorderSum > maxLeftBorderSum ? maxRightBorderSum : maxLeftBorderSum;
        int h =  (maxRightBorderSum +maxLeftBorderSum) > k?(maxRightBorderSum +maxLeftBorderSum):k;
        return h;
    }
    
    
    
    /**
     * // 最大/子序列和<br>
     * 最大子序列: 任何负的子序列不可能是最大子序列的前缀<br>
     * 最小子序列: 任何正的子序列不可能是最小子序列的前缀
     * @param a
     * @return
     */
    private static int maxSubSum(int[] a){
        int maxSub = a[0];
       int  maxSum = 0;
        for(int i = 0;i<a.length;i++){
            maxSum += a[i];
//            if(maxSub<maxSum){  // 最大子序列和 else if(maxSum<0
            if(maxSub>maxSum){ //最小子序列和 else if(maxSum>0
                maxSub = maxSum;
            }else if(maxSum>0){
                maxSum = 0;
            }
        }
        return maxSub;
    } 
  //折半查找
    private static <AnyType extends Comparable<? super AnyType>> int  binary(AnyType[] a,AnyType x){
        int low = 0,hight = a.length;
        while(low<=hight){
            int mid = (low+hight)/2;
            if(a[mid].compareTo(x)<0){
                low = mid +1;
            }else if(a[mid].compareTo(x)>0){
                hight = mid -1;
            }else{
                return mid;
            }
        }
        return -1;
    }
   
 
    //欧几里德算法
    private static long gcd(long m,long n){
        while(n!= 0){
            long rem = m%n;
            m= n;
            n = rem;//余数里包含最大公因数
        }
        return m;
    }
 
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值