The maximum-subarray problem

package com.zkdx.test;

import java.util.HashMap;

/**
 * @Author: Chintsai Hwo
 * @Date: Created on 8:37 PM 6/27/2019
 */
public class Test {
    public static void main(String[] args) {
        int[] a = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};

        // 用暴力破解法
        HashMap<Integer, Integer> indices = findIndex(a);
        System.out.println(indices);

        System.out.println();

        // 用分治法
        int[] subarray = findMaximumSubarray(a, 0, a.length - 1);
        for (int element : subarray)
            System.out.println(element + " ");
    }


    /**
     * brute-force method, which is of complexity n^2 and is not recommended.
     *
     * @param a
     * @return
     */
    private static HashMap<Integer, Integer> findIndex(int[] a) {
        HashMap<Integer, Integer> indices = new HashMap<>();
        int sum;
        int maxSum = Integer.MIN_VALUE;
        int min = 0;
        int max = 0;
        for (int i = 0; i < a.length; i++) {
            sum = 0;
            for (int j = i; j < a.length; j++) {
                sum += a[j];
                if (sum > maxSum) {
                    maxSum = sum;
                    max = j;
                    min = i;
                }
            }
        }
        indices.put(min, max);
        return indices;
    }

    /**
     * divide-and-conquer method, which is of complexity n*lg(n) and is highly recommended.
     */
    private static int[] findMaxCrossingSubarray(int[] a) {
        int[] subarray;
        int low = 0;
        int high = a.length - 1;
        int mid = (low + high) / 2;
        int sum = 0;
        int maxLeft = mid;
        int maxRight = mid + 1;
        int leftSum = Integer.MIN_VALUE;
        int rightSum = Integer.MIN_VALUE;
        for (int i = mid; i > 0; i--) {
            sum += a[i];
            if (sum > leftSum) {
                leftSum = sum;
                maxLeft = i;
            }
        }
        sum = 0;
        for (int j = mid + 1; j <= high; j++) {
            sum += a[j];
            if (sum > rightSum) {
                rightSum = sum;
                maxRight = j;
            }
        }
        subarray = new int[]{maxLeft, maxRight, leftSum + rightSum};
        return subarray;
    }

    /**
     * @param a
     * @param low
     * @param high
     * @return
     */
    private static int[] findMaximumSubarray(int[] a, int low, int high) {
        int[] subarray;
        if (low == high)
            return new int[]{low, high, a[low]};
        else {
            int mid = (low + high) / 2;
            int leftLow = findMaximumSubarray(a, low, mid)[0];
            int leftHigh = findMaximumSubarray(a, low, mid)[1];
            int leftSum = findMaximumSubarray(a, low, mid)[2];
            int rightLow = findMaximumSubarray(a, mid + 1, high)[0];
            int rightHigh = findMaximumSubarray(a, mid + 1, high)[1];
            int rightSum = findMaximumSubarray(a, mid + 1, high)[2];
            int crossLow = findMaxCrossingSubarray(a)[0];
            int crossHigh = findMaxCrossingSubarray(a)[1];
            int crossSum = findMaxCrossingSubarray(a)[2];
            if (leftSum >= rightSum && leftSum >= crossSum)
                return new int[]{leftLow, leftHigh, leftSum};
            else if (rightSum >= leftSum && rightSum >= crossSum)
                return new int[]{rightLow, rightHigh, rightSum};
            else
                return new int[]{crossLow, crossHigh, crossSum};
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章