最大子数组:求连续数组的最大和问题,也就是说数组的那个连续子数组的和最大.(我的理解)算法
主要思想经过分治法,最大子数组只能有三种状况:中间元素的左边取得;中间元素的右边取得;跨越中间元素取得. 能够经过mind=(low+high)/2分解,把元问题分解成更小的子问题。数组
代码以下 ArrarType表示找到的最大子数组相应的左右边界和值ide
package com.lifeStudy.algorith; public class ArrarTypes { private int max_left; private int max_right; private int max_sum; @Override public String toString() { return "ArrarTypes: max_left=" + max_left + " max_right=" + max_right + " max_sum=" + max_sum; } public ArrarTypes(int max_left, int max_right, int max_sum) { this.max_left = max_left; this.max_right = max_right; this.max_sum = max_sum; } public void setMax_left(int max_left) { this.max_left = max_left; } public void setMax_right(int max_right) { this.max_right = max_right; } public void setMax_sum(int max_sum) { this.max_sum = max_sum; } public int getMax_left() { return max_left; } public int getMax_right() { return max_right; } public int getMax_sum() { return max_sum; } }
求解算法代码this
package com.lifeStudy.algorith; //求解最小子数组问题 分治法 public class TheMaxSubArray { /** * @param A 待求数组 * @param low 最小的位置序列 * @param mid 中间的位置序列 * @param high 最大的位置序列 * @return 返回数组A 中跨越中间位置的最大数组和 包括起始和结束边界、最大的和值 */ //求出数组A跨越中点mid的最大数组和 public static ArrarTypes find_max_crossing_subArray(int[] A, int low, int mid, int high) { //求出左边数据的最大和 int left_sum = Integer.MIN_VALUE; int max_left = mid;//记录左边最大和的边界位置 int sum = 0; for (int i = mid; i >= low; i--) { sum += A[i]; if (sum > left_sum) { left_sum = sum; max_left = i; } } //求出右边数据的最大和 int right_sum = Integer.MIN_VALUE; int max_right = mid + 1; sum = 0; for (int j = mid + 1; j <= high; j++) { sum += A[j]; if (sum > right_sum) { right_sum = sum; max_right = j; } } return new ArrarTypes(max_left, max_right, left_sum + right_sum); } /** * @param A 目标数组 * @param low 数组最小位置 * @param high 数组最大位置 * @return */ //查找出最大和数组 包含三种状况 在数组集合的左边;在数组集合的右边;跨越数组中心元素集合 public static ArrarTypes find_max_subArray(int[] A, int low, int high) { if (low > high) { return null; } if (low == high) { return new ArrarTypes(low, high, A[low]); } else { int mid = (low + high) / 2; ArrarTypes max_subArrayleft = find_max_subArray(A, low, mid); ArrarTypes max_subArrayright = find_max_subArray(A, mid + 1, high); ArrarTypes max_crossing_subArray = find_max_crossing_subArray(A, low, mid, high); if (max_crossing_subArray.getMax_sum() > max_subArrayleft.getMax_sum() && max_crossing_subArray.getMax_sum() > max_subArrayright.getMax_sum()) { return max_crossing_subArray; } else if (max_subArrayleft.getMax_sum() > max_crossing_subArray.getMax_sum() && max_subArrayleft.getMax_sum() > max_subArrayright.getMax_sum()) { return max_subArrayleft; } else{ return max_subArrayright; } } } public static void main(String... args) { int a[] = new int[]{13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}; ArrarTypes max_subArray = find_max_subArray(a, 0, a.length - 1); System.out.println(max_subArray.toString()); } }
线性时间实现求最大子数组问题·spa
原理:例如A[1.....j]的最大子数组已知,那么A[1......j+1]的最大子数组要么是前一个元素的最大子数组,或者是A[i....j+1]为最大子数组
能够经过比较前一个最大子数组和边界最大子数组(包含最后一个元素) 的大小code
package com.lifeStudy.algorith; //求线性时间的最大子数组问题 public class TheMaxSubArrayLinearTime { //原理:例如A[1.....j]的最大子数组已知,那么A[1......j+1]的最大子数组要么是前一个元素的最大子数组,或者是A[i....j+1]为最大子数组 private static int[] boundryMax;//边界最大子数组 当前元素的最大子数组等于前一个元素的最大子数组或者前一个元素的边界子数组加当前元素或者等于当前元素 private static int[] valueMax;//最大子数组 private static int[][] pos;//最大子数组的边界位置信息 public static void InitDatas(int vales[]) { boundryMax = new int[vales.length]; valueMax = new int[vales.length]; //初始化第一个元素的边界最大子数组和最大子数组 boundryMax[0] = vales[0]; valueMax[0] = vales[0]; pos = new int[vales.length][2]; pos[0][1] = pos[0][0] = 0; //求出每个子数组的最大子数组 for (int i = 1; i < vales.length; i++) { int beforeValueMax = valueMax[i - 1];//前一个最大子数组 int currentValue = vales[i]; int beforeBoundryMax = boundryMax[i - 1] + currentValue; int max = beforeValueMax > currentValue ? (beforeValueMax > beforeBoundryMax ? beforeValueMax : beforeBoundryMax) : (currentValue > beforeBoundryMax ? currentValue : beforeBoundryMax); valueMax[i] = max; boundryMax[i] = beforeBoundryMax > currentValue ? beforeBoundryMax : currentValue; } } public static void main(String... args) { int a[] = new int[]{13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7, 0}; InitDatas(a); System.out.println(valueMax[valueMax.length - 1]); } }