求最大子列和

package MaxSubseqSum;

public class MaxSubseqSumDemo {
	// 使用三个嵌套循环计算最大子列和,时间复杂度为 O(n^3)
	public int getMaxSubseqSum1(int[] a, int n) {
		int i, j, k, ThisSum, MaxSum = 0;
		for (i = 0; i < n; i++) {
			for (j = i; j < n; j++) {
				ThisSum = 0;
				for (k = i; k <= j; k++) {
					ThisSum += a[k];
				}
				if (ThisSum > MaxSum) {
					MaxSum = ThisSum;
				}
			}
		}
		return MaxSum;
	}

	// 使用二个嵌套循环计算最大子列和 时间复杂度为 O(n^2)
	public int getMaxSubseqSum2(int[] a, int n) {
		int i, j, ThisSum, MaxSum = 0;
		for (i = 0; i < n; i++) {
			ThisSum = 0;
			for (j = i; j < n; j++) {
				ThisSum += a[j];
				if (ThisSum < 0) {
					ThisSum = 0;
				}
				if (ThisSum > MaxSum) {
					MaxSum = ThisSum;
				}
			}
		}
		return MaxSum;
	}

	// 使用分治法实现计算最大子类和的问题,时间复杂度为 O(nlg(n))
	// 使用递归来实现分治
	public int getMax(int maxMidSum, int maxLeftSum, int maxRightSum) {
		int max;
		if (maxMidSum > maxLeftSum) {
			max = maxMidSum;
		} else {
			max = maxLeftSum;
		}
		if (max < maxRightSum) {
			max = maxRightSum;
		}
		return max;
	}

	public int getMaxSubseqSum3(int[] a, int left, int right) {
		// 设置推出条件,如果<0返回0
		if (left == right) {
			if (a[left] > 0) {
				return left;
			} else {
				return 0;
			}
		}

		// 递归左右两边需要分治的部分得到两边的最大最小值
		int center = (left + right) / 2;
		int maxLeftSum = getMaxSubseqSum3(a, left, center);
		int maxRightSum = getMaxSubseqSum3(a, center + 1, right);

		// 对于跨国中间部分的最值需要对本层递归进行特殊处理
		int maxLeftBorderSum = 0;
		int leftBorderSum = 0;

		for (int i = center; i >= left; i--) {
			leftBorderSum += a[i];
			if (leftBorderSum > maxLeftBorderSum) {
				maxLeftBorderSum = leftBorderSum;
			}
		}

		int maxRightBorderSum = 0;
		int rightBorderSum = 0;
		for (int i = center + 1; i <= right; i++) {
			rightBorderSum += a[i];
			if (rightBorderSum > maxRightBorderSum) {
				maxRightBorderSum = rightBorderSum;
			}
		}
		return getMax(maxLeftBorderSum + maxRightBorderSum, maxLeftSum,
				maxRightSum);
	}

	// 使用在线处理的方法计算最大子列和问题,时间复杂度为O(n),目前时间复杂度最好的算法了
	public int getMaxSubseqSum4(int[] a, int n) {
		int thisSum = 0;
		int maxSum = 0;
		for (int i = 0; i < n; i++) {
			thisSum += a[i];
			if (thisSum > maxSum) {
				maxSum = thisSum;
			}
			if (thisSum < 0) {
				thisSum = 0;
			}
		}
		return maxSum;
	}
}

package MaxSubseqSum;

public class MaxSubseqSumTest {
	public static void main(String[] args) {
		int[] a = { 1, 2, 3, -6, 5, 2, 1 };
		MaxSubseqSumDemo Max = new MaxSubseqSumDemo();
		int max1 = Max.getMaxSubseqSum1(a, a.length);
		int max2 = Max.getMaxSubseqSum2(a, a.length);
		int max3 = Max.getMaxSubseqSum3(a, 0, a.length - 1);
		int max4 = Max.getMaxSubseqSum4(a, a.length);
		System.out.println(max1);
		System.out.println(max2);
		System.out.println(max3);
		System.out.println(max4);
	}
}

posted @ 2018-02-28 16:53  wei1  阅读(127)  评论(0编辑  收藏  举报