首页 > 代码库 > 最大子序列
最大子序列
package alg;/** * 求取最大的子数列 * */public class SubMaxArray { public static void main(String[] args) { int[] a = new int[] { 1, -2, 3, 10, -4, 7, 2, -5 }; int[] b = new int[] { -6, 2, 4, -7, 5, 3, 2, -1, 6, -9, 10, -2 }; int max = maxSum(a, a.length); System.out.println(max); int maxb = maxSum(b, b.length); System.out.println(maxb); long wmax = maxSubSum4(a); System.out.println(wmax); long malxb = maxSubSum4(b); System.out.println(malxb); } // 暴力的循环 static int maxSum(int[] A, int n) { int maximum = Integer.MIN_VALUE; int sum = 0; for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { for (int k = i; k <= j; k++) { sum += A[k]; } if (sum > maximum) { maximum = sum; } sum = 0; // 这里要记得清零,否则的话sum最终存放的是所有子数组的和。 } } return maximum; } // 省略重复的计算 static int maxSumModify(int[] a) { int maxSum = 0; for (int i = 0; i < a.length; i++) { int thisSum = 0; for (int j = i; j < a.length; j++) { thisSum += a[j]; if (thisSum > maxSum) maxSum = thisSum; } } return maxSum; } /** * 分治算法 最大的子数列,在前半部分,在后半部分 或者从中间进行计算 * */ static long maxSumRec(int[] a, int left, int right) { if (left == right) { if (a[left] > 0) return a[left]; else return 0; } int center = (left + right) / 2; long maxLeftSum = maxSumRec(a, left, center); long maxRightSum = maxSumRec(a, center + 1, right); // 求出以左边对后一个数字结尾的序列最大值 long maxLeftBorderSum = 0, leftBorderSum = 0; for (int i = center; i >= left; i--) { leftBorderSum += a[i]; if (leftBorderSum > maxLeftBorderSum) maxLeftBorderSum = leftBorderSum; } // 求出以右边对后一个数字结尾的序列最大值 long maxRightBorderSum = 0, rightBorderSum = 0; for (int j = center + 1; j <= right; j++) { rightBorderSum += a[j]; if (rightBorderSum > maxRightBorderSum) maxRightBorderSum = rightBorderSum; } return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); } static long maxSubSum3(int[] a) { return maxSumRec(a, 0, a.length - 1); } static long max3(long a, long b, long c) { if (a < b) { a = b; } if (a > c) return a; else return c; } // 线性的算法O(N) /** * 算法的基础:如果a[i] 为负数,那么他不可能是最大子序列的开始,推论是最大子数列的开头的数组的和不可能是一个负数, * 也就是说为负数的子序列不可能是最大子序列的开始。 * */ static long maxSubSum4(int[] a) { long maxSum = 0, thisSum = 0; for (int j = 0; j < a.length; j++) { thisSum += a[j]; if (thisSum > maxSum) maxSum = thisSum; else if (thisSum < 0) thisSum = 0; } return maxSum; } /** * 如果全部为负数的情况下,最大的子序列是为一个元素都没有的零, * 还是最大的负数? * */ static int maxsum(int[] a) { int max = a[0]; // 全负情况,返回最大数 int sum = 0; for (int j = 0; j < a.length; j++) { if (sum >= 0){ // 如果加上某个元素,sum>=0的话,就加 sum += a[j]; }else{ sum = a[j]; // 如果加上某个元素,sum<0了,就不加 } if (sum > max) max = sum; } return max; }}
最大子序列
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。