• 分治法-最大子数组问题


    寻找数组A的和最大的非空连续子数组。例如:数组
    A = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}的和最大的连续子数组为{18, 20, -7, 12},最大和为43,所以{18, 20, -7, 12}就是A的最大子数组;
    数组{1, -4, 3, -4}的最大子数组为{3}。

    采用分治策略:将数组分为两个规模相等的子数组,分别求子数组的最大子数组,以及跨越中点的最大子数组,然后将左子数组、右子数组、跨越中点三种情况的最大子数组比较取最大值。

    Java代码实现:

    class FindMaximumSubArray
    {
    public static void main(String[] args)
    {
    int[] arr = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
    SubArray max_subarray = find_maximum_subarray(arr, 0, arr.length - 1);
    System.out.println("low:" + max_subarray.low + ", high:" + max_subarray.high + ", sum:" + max_subarray.sum);
    }

    // 查找最大子数组
    private static SubArray find_maximum_subarray(int[] arr, int low, int high) {
    if (low == high) {
    return new SubArray(low, high, arr[low]);
    } else {
    int mid = (low + high) / 2;
    SubArray left = find_maximum_subarray(arr, low, mid);// 递归求左子数组中的最大子数组
    SubArray right = find_maximum_subarray(arr, mid + 1, high);// 递归求右子数组中的最大子数组
    SubArray cross = find_max_crossing_subarray(arr, low, mid, high);// 求跨越中点的最大子数组
    if (left.sum >= right.sum && left.sum >= cross.sum) {
    return left;
    } else if (right.sum >= left.sum && right.sum >= cross.sum) {
    return right;
    } else return cross;
    }
    }

    // 查找包含中点的最大子数组
    private static SubArray find_max_crossing_subarray(int[] arr, int low, int mid, int high) {
    int left_sum = arr[mid];
    int max_left = mid;
    int sum = 0;
    for (int i = mid; i >= low; i--) {// 左边最大和
    sum += arr[i];
    if (sum > left_sum) {
    left_sum = sum;
    max_left = i;
    }
    }
    int right_sum = arr[mid + 1];
    int max_right = mid + 1;
    sum = 0;
    for (int i = mid + 1; i <= high; i++) {// 右边最大和
    sum += arr[i];
    if (sum > right_sum) {
    right_sum = sum;
    max_right = i;
    }
    }
    return new SubArray(max_left, max_right, left_sum + right_sum);
    }

    private static class SubArray {
    int low;
    int high;
    int sum;

    SubArray(int low, int high, int sum) {
    this.low = low;
    this.high = high;
    this.sum = sum;
    }
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    该算法的运行时间为Θ(nlgn)。
    ---------------------

  • 相关阅读:
    基于 Token 的身份验证
    学以致用二---配置Centos7.2 基本环境
    学以致用一 安装centos7.2虚拟机
    #!/usr/bin/env python与#!/usr/bin/python的区别
    centos7.2下安装python3.6.2
    Day1-python基础-变量常量
    Day1-python基础
    学python之路前的一些话
    Mybatis generator自动生成mybatis配置和类信息
    MyBatis Generator generatorConfig.xml配置详解
  • 原文地址:https://www.cnblogs.com/hyhy904/p/11257584.html
Copyright © 2020-2023  润新知