zoukankan      html  css  js  c++  java
  • 分治策略---求最大子数组

    只有当数组中包含负数时,最大子数组问题才有意义。如果所有元素都是非负的,最大子数组问题没有任何意义,因为整个数组和肯定是最大的

     1 public class FindMaxSubArrayDemo {
     2     public static void main(String[] args) {
     3         int[] arr = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
     4         int[] result_arr = findMaximumSubarray(arr, 0, arr.length - 1);
     5         for (int i = 0; i < result_arr.length; i++) {
     6             System.out.println(result_arr[i]);
     7         }
     8     }
     9 /*
    10 最大数组问题:使用分治策略
    11     分析:1.要将大数组划分为两个规模尽量相等的子数组,也就是找到大数组的中央位置mid,
    12          2.求解两个子数组A[low,mid]和A[mid+1,high]
    13          3,那么所求的最大数组A[i,j]就只用三种情况
    14             * 第一种情况:完全位于A[low,mid],因此low <= i <= j <= mid;
    15             * 第二种情况:完全位于A[mid+1,high],因此 mid+1 <= i <= j <= high;
    16             * 第三种情况:跨越了中点,因此low <= i <= mid j <= high;
    17          4.可以递归第一种和第二种情况的最大子数组问题,因为两个子问题仍然是最大数组问题,只是规模更小
    18          5.因此,只要寻找跨越中点的最大子数组
    19          6.最后进行三者比较选取最大值的问题。
    20  */
    21     public static int[] findMaxCrossingSubArray(int[] arr, int low, int mid, int high) {//找出跨越中点最大子数组的方法
    22         int left_sum = arr[low];//存储左半部的和
    23         int sum = 0; //存储元素和,来分别与左右半部的和进行比较
    24         int right_sum = arr[high]; //存取右半部的和
    25         int max_left = 0; //存取最左边的角标
    26         int max_right = 0;//存取最右边的角标
    27         int[] result_arr = new int[3];
    28         for (int i = mid; i >= low; i--) {
    29             sum = sum + arr[i];
    30             if (sum > left_sum) {
    31                 left_sum = sum;
    32                 max_left = i;
    33             }
    34         }
    35         sum = 0;
    36         for (int i = mid + 1; i <= high; i++) {
    37             sum = sum + arr[i];
    38             if (sum > right_sum) {
    39                 right_sum = sum;
    40                 max_right = i;
    41             }
    42         }
    43         result_arr[0] = max_left;
    44         result_arr[1] = max_right;
    45         result_arr[2] = left_sum + right_sum;
    46         return result_arr;
    47     }
    48 
    49     public static int[] findMaximumSubarray(int[] arr, int low, int high) {
    50         int[] result_arr = new int[3];
    51         if (high == low) {  //base case: only one element
    52             result_arr[0] = low;
    53             result_arr[1] = high;
    54             result_arr[2] = arr[low];
    55             return result_arr;
    56         } else {
    57             int mid = (low + high) / 2;
    58             int[] left_result_arr = findMaximumSubarray(arr, low, mid); //第一种情况
    59             int[] right_result_arr = findMaximumSubarray(arr, mid + 1, high); //第二种情况
    60             int[] cross_result_arr = findMaxCrossingSubArray(arr, low, mid, high); //第三种情况
    61             if (left_result_arr[2] >= right_result_arr[2] && left_result_arr[2] >= cross_result_arr[2]) {
    62                 return left_result_arr;
    63             } else if (right_result_arr[2] >= left_result_arr[2] && right_result_arr[2] >= cross_result_arr[2]) {
    64                 return right_result_arr;
    65             } else {
    66                 return cross_result_arr;
    67             }
    68         }
    69     }
    70 }
  • 相关阅读:
    熟悉常用的Linux操作
    Python基础之五星红旗
    类似于铁道部12306的城市选择框的实现
    使用Django操作数据库入门
    进程和线程
    线程、进程、携程理解
    CentOS6.8部署Python3.6.8的Django项目
    爬取妹子图片
    聚类算法之DBSCAN
    机器学习算法优缺点总结
  • 原文地址:https://www.cnblogs.com/Joe-666/p/9463085.html
Copyright © 2011-2022 走看看