最大子序列和及其位置问题
2014-10-15 15:09
127 查看
/** * 文件名:MaxSubSumText.java * 时间:2014年10月21日下午6:09:36 * 作者:修维康 */ package chapter3; import java.util.*; /** * 类名:MaxSubSumTest.java * 说明:求最大子序列和的几种算法 */ public class MaxSubSumTest { /** * 函数名称:maxSubSum1 * 说明:时间复杂度O(n^3) */ static int[] maxSubSum1(int[] a) { int max = 0;// 最小的返回0 int[] result = null;// result[0]代表序列的开始下标[1]代表结束下标[2]代表和 for (int i = 0; i < a.length; i++) { for (int j = i; j < a.length; j++) { int sum = 0; for (int k = i; k <= j; k++) { sum += a[k]; } if (sum > max) { max = sum; result = new int[] { i, j, max }; } } } return result; } /** * 函数名称:maxSubSum2 * 说明:时间复杂度O(n^2) */ static int[] maxSubSum2(int[] a) { int max = 0; int[] result = null; for (int i = 0; i < a.length; i++) { int sum = 0; for (int j = i; j < a.length; j++) { sum = sum + a[j]; if (sum > max) { max = sum; result = new int[] { i, j, max }; } } } return result; } /** * 函数名称:maxSubSum3 * 说明:递归分治求解 时间复杂度O(NlogN) */ static int[] maxSubSum3(int[] a, int left, int right) { if (left == right)// 最基础的(递归返回条件) return new int[] { left, right, a[left] }; int center = (left + right) / 2; int[] maxLeft = maxSubSum3(a, left, center); int[] maxRight = maxSubSum3(a, center + 1, right); int maxLeftBorderSum = -1000; int leftBorderSum = 0; int leftFlag = 0;// 最大的左边位置 for (int i = center; i >= left; i--) { leftBorderSum += a[i]; if (leftBorderSum > maxLeftBorderSum) { maxLeftBorderSum = leftBorderSum; leftFlag = i; } } int[] result = new int[3];// result数组记录跨过中间的 result[0] = leftFlag; int maxRightBorderSum = -1000; int rightBorderSum = 0; int rightFlag = 0; for (int i = center + 1; i <= right; i++) { rightBorderSum += a[i]; if (rightBorderSum > maxRightBorderSum) { maxRightBorderSum = rightBorderSum; rightFlag = i; } } result[1] = rightFlag; result[2] = maxRightBorderSum + maxLeftBorderSum; return (maxLeft[2] > maxRight[2] ? maxLeft : maxRight)[2] > result[2] ? (maxLeft[2] > maxRight[2] ? maxLeft : maxRight) : result; } /** * 函数名称:maxSubSum4 * 说明:时间复杂度O(N)// */ public static int[] maxSubSum4(int a[]) { int[] result = new int[3]; int sum = 0, flag = 0; result[2] = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; if (sum > result[2]) { result[2] = sum; if ((flag++) == 0) result[0] = i; result[1] = i; } else if (sum < 0) { sum = 0; flag = 0; } } return result; } public static void main(String[] args) { // TODO 自动生成的方法存根 int[] a = new int[] { -1, 2, -5, 7, 8, -5 }; System.out.println(Arrays.toString(maxSubSum1(a))); System.out.println(Arrays.toString(maxSubSum4(a))); System.out.println(Arrays.toString(maxSubSum3(a, 0, a.length - 1))); System.out.println(Arrays.toString(maxSubSum4(a))); } }
相关文章推荐
- 最大子序列和问题及其起始位置
- 最大子序列问题及其求解----C 语言学习
- 子序列最大和问题及其推广
- 最大子序列和问题以及确定序列起终点位置
- 最大子序列问题及其求解
- 求最大子序列和及其位置(四种经典方法)
- 最大连续子序列和及其起始位置(未测试)
- 经典的求数组中最大值及其位置的问题.
- 最大子序列和问题 二维最大子序列核问题及其优化
- 最大子序列问题及其求解
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(3) 最大子序列和问题
- 最大子序列问题
- 最大子序列和问题 一步一步到最优
- 子序列之和的最大值,并且返回子序列的位置 Contains Negtive
- 对“最大子序列和问题”的一点思考
- 最大和子序列问题
- 最大/小和子序列问题
- 最大子序列和问题
- 最大和子序列问题
- POJ 1952 BUY LOW BUY LOWER 【DP】最长降序子序列及其计数问题