最大子段和(暴力法、改进暴力法、分治法、动态规划法)(java)

1、暴力法

public class MaxSum {
     
    public static int Sum(int[] array, int n) {
     
        if (array == null || array.length == 0)
            return 0;
        else {
     
            int MaxSum = 0;
            for (int i = 0; i < n; i++) {
     //先定开始的下标
                for (int j = 0; j < n; j++) {
     //后定结束的下标
                    int Sum = 0;//注意这里令Sum=0,在第二个for之后,想想为什么?因为改变结束的元素下标后,从头开始找子段,此时令Sum=0
                    for (int k = i; k <= j; k++) {
     //在开始的下标与结束的下标之间移动k,从前往后找子段和
                        Sum = Sum + array[k];//array[K]叠加,后面的array[k]加到原来的Sum里
                        if (Sum > MaxSum)
                            MaxSum = Sum;
                    }
                }
            }
            return MaxSum;
        }
    }

    public static void main(String[] args) {
     
        int[] a = {
     4, -3, 5, -2, -1, 2, 6, -2};
        int n = a.length;
        int result = Sum(a, n);
        System.out.println("最大字段和 = "+result);
    }
}

  比较容易想到,又蠢又笨的方法(看了方法2的分治法就知道为什么又蠢又笨了),用了3个for循环,时间复杂度为O(n^3)。
  
  a = {4, -3, 5, -2, -1, 2, 6, -2}
最大子段和(暴力法、改进暴力法、分治法、动态规划法)(java)_第1张图片

2、改进暴力法

  相对于方法1,就是把方法1的第三个for的if放在第二for里,不要第三个for,用第二个for改变结束下标的同时进行k寻找。时间复杂度为O(n^2)。

public class MaxSum1 {
     
    public static int Max(int[] array, int n) {
     
        if(array.length==0||array==null)
            return 0;
        else {
     
            int MaxSum = 0;
            for (int i = 0; i < n; i++) {
     
                int Sum = 0;
                for (int j = i; j < n; j++) {
     //改变结束下标的同时(j=i),进行寻找字段和(j++)。
                    Sum = Sum + array[j];
                    if (Sum > MaxSum) {
     
                        MaxSum = Sum;
                    }
                }
            }
            return MaxSum;
        }
    }

    public static void main(String[] args) {
     
        int[] a = {
     -2,11,-4,13,-5,-2};
        int n = a.length;
        int result = Max(a, n);
        System.out.println("最大子段和 = "+result);

    }
}

  a = {-2,11,-4,13,-5,-2}
最大子段和(暴力法、改进暴力法、分治法、动态规划法)(java)_第2张图片

3、分治法

  从中间划分两个区域,在这两个区域内分别用方法1的第三个for。其实就是“二分法”+方法1/2的改进法。时间复杂度为O(nlogn)。(有种换汤不换药的感觉,只是加了二分法)

public class MaxSum2 {
     
    public static int Max(int[] array, int left, int right) {
     
        if (array == null || array.length == 0)
            return 0;
        int center = (left + right) / 2;
        int Sum1 = 0;
        int Sum_left = 0;
        for (int i = center; i >= left; i--) {
     //左半部分最大子段和
            Sum1 = Sum1 + array[i];
            if (Sum_left < Sum1) {
     
                Sum_left = Sum1;
            }
        }

        int Sum2 = 0;
        int Sum_right = 0;
        for (int j = center + 1; j <= right; j++) {
     //右半部分子段和
            Sum2 = Sum2 + array[j];
            if (Sum_right < Sum2) {
     
                Sum_right = Sum2;
            }
        }

        int Sum = Sum_left + Sum_right;//左右相加的子段和
        if (Sum < Sum_left)
            Sum = Sum_left;
        if (Sum < Sum_right)
            Sum = Sum_right;
        return Sum;//左、右、左+右 三部分子段和比较,取最大者
    }

    public static void main(String[] args) {
     
        int[] a = {
     6, -1, 5, 4, -7};
        int left = 0;
        int right = a.length - 1;
        int Max = Max(a, left, right);
        System.out.println("最大子段和 = " + Max);
    }
}

4、动态递归法

  动态规划递归式:b [ j ] = max { b [ j-1 ] + a [ j ], a [ j ] }

  时间复杂度为O(n)

public class MaxSum3 {
     
    public static int Max(int array[], int n) {
     
        int Sum = 0;
        int b = 0;//b是个打工仔,从头求到尾,求子段和。
        for (int i = 0; i < n; i++) {
     
            if (b > 0)
                b = b + array[i];
            else
                b = array[i];
            if (b > Sum)//用Sum来记录前面已经求出来的最大字段和,这样就不必重复计算。
                Sum = b;

        }
        return Sum;
    }

    public static void main(String[] args) {
     
        int[] a = {
     -2,11,-4,13,-5,-2};
        int n = a.length - 1;
        int result = Max(a, n);
        System.out.println("最大子段和 = " + result);
    }
}

你可能感兴趣的:(最大子段和(暴力法、改进暴力法、分治法、动态规划法)(java))