算法------编程珠玑(ProgrammingPeals)第八章(JAVA)

package code_08_chapter;

/*
 *Created by William on 2018/6/22 0022
 */
public class QuestionsInChapter8 {
    /**
     * 给定一个含有n个元素的vector,找出其中最大的子向量(即所有元素之和为最大值)。
     * 如果是都为正数,那么问题变得十分简单,整个vector即是最大子向量,但是如果是正数负数混合的形式呢?
     * 问题将变得复杂,接下来将简要介绍几种算法的思路。其复杂度由最初的立方算法降低到最终的线性算法!
     * (提供的代码细节处如数据类型例如int之类自己根据情况填加)
     */
    //立方算法,思想很简单,即遍历所有情况:
    public static int cubicAlgorithm(int[] array) {
        int maxfactor = 0;
        int sum;
        int length = array.length;
        for (int i = 0; i < length; i++) {
            for (int j = i; j < length; j++) {
                sum = 0;
                for (int k = i; k < j; k++) {
                    sum += array[k];
                }
                maxfactor = Math.max(maxfactor, sum);
            }
        }
        return maxfactor;
    }

    //其实不必每有一个[i,j]便重新求和一次,可以在遍历的过程中进行求和,因此,可以降低算法的复杂度为平方算法:Square algorithm
    public static int squareAlgorithm(int[] array) {
        int maxfactor = 0;
        int length = array.length;
        int sum;
        for (int i = 0; i < length; i++) {
            sum = 0;
            for (int j = i; j < length; j++) {
                sum += array[j];
                maxfactor = Math.max(maxfactor, sum);
            }
        }
        return maxfactor;
    }

    //使用常见的分治算法又可以进一步的降低算法的复杂度O(nlogn):Divide and conquer algorithm
    public static int divideAndConquerAlgorithm(int l, int u, int[] array) {
        if (l > u) return 0;    // zero elements
        if (l == u) return Math.max(0, array[l]);   //one element
        int sum;
        int m = (l + u) / 2;
        // find max crossing to left
        int leftMax;
        leftMax = sum = 0;
        for (int i = m; i >= l; i--) {
            sum += array[i];
            leftMax = Math.max(leftMax, sum);
        }
        // find max crossing to right
        int rightMax;
        rightMax = sum = 0;
        for (int q = m + 1; q <= u; q++) {
            sum += array[q];
            rightMax = Math.max(rightMax, sum);
        }
        return tripleMax(leftMax + rightMax, divideAndConquerAlgorithm(l, m, array), divideAndConquerAlgorithm(m + 1, u, array));
    }
    public static int tripleMax(int a, int b, int c) {
        int temp = Math.max(a, b);
        return Math.max(temp, c);
    }

    //扫描算法,思路借鉴分治算法,不过使复杂度达到最低O(n),即线性算法:
    public static int scanningAlgorithm(int[] arr){
        int maxSoFar = 0;
        int maxEndingHere = 0;
        int n = arr.length;
        for(int i =0; i< n; i++){
            maxEndingHere = Math.max(maxEndingHere+arr[i],0);
            maxSoFar = Math.max(maxSoFar,maxEndingHere);
        }
        return maxSoFar;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{31, -41, 59, 26, -53, 58, 97, -93, -23, 84};
        System.out.println(cubicAlgorithm(arr));
        System.out.println(squareAlgorithm(arr));
        System.out.println(divideAndConquerAlgorithm(0, arr.length - 1, arr));
        System.out.println(scanningAlgorithm(arr));
    }
}

猜你喜欢

转载自blog.csdn.net/weianluo/article/details/80776109