首页 > 代码库 > 求一数字序列的最大子段和(三种解法)
求一数字序列的最大子段和(三种解法)
import java.util.Scanner; public class MaxSum { public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.println("请输入整数个数:"); int N = scan.nextInt(); int[] arr = new int[N]; System.out.println("请输入整数序列(各数据间用空格隔开):"); for(int i=0;i<N;i++){ arr[i] = scan.nextInt(); } System.out.println("各算法所求最大子段和分别为:"); System.out.println("分治算法最优值:" + maxSumDiv(arr, 0, arr.length - 1)); System.out.println("==========================="); maxSumDp(arr); System.out.println("==========================="); maxSumSimp(arr, 0, 0); } // 简单算法(需要O(n^2)计算时间) public static void maxSumSimp(int arr[], int bestx, int besty) { int n = arr.length, sum = 0; for (int i = 1; i <= n; i++) { int thissum = 0; //改变子段和的首数字时,须将当前的子段和清零 for (int j = i; j <= n; j++) { thissum += arr[j - 1]; if (thissum > sum) { sum = thissum; bestx = i; besty = j; } } } System.out.println("简单算法最优值:" + sum); System.out.println("最优解:" + bestx + "-->" + besty); } // 分治算法实现(需要O(nlogn)的计算时间) public static int maxSumDiv(int[] arr, int left, int right) { int sum = 0; if (left == right) { sum = arr[left] > 0 ? arr[left] : 0; } else { int center = (left + right) / 2; int leftSum = maxSumDiv(arr, left, center); int rightSum = maxSumDiv(arr, center + 1, right); int s1 = 0; int lefts = 0; for (int i = center; i >= left; i--) { lefts += arr[i]; if (lefts > s1) { s1 = lefts; } } int s2 = 0; int rights = 0; for (int i = center + 1; i <= right; i++) { rights += arr[i]; if (rights > s2) { s2 = rights; } } sum = s1 + s2; if (sum < leftSum) { sum = leftSum; } if (sum < rightSum) { sum = rightSum; } } return sum; } // 动态规划算法实现(只需要O(n)计算时间和O(n)空间) public static void maxSumDp(int[] arr) { int sum = 0, b = 0, n = arr.length, bestx = 0, besty = 0; for (int i = 1; i <= n; i++) { //b是累加和 if (b > 0) { b += arr[i - 1]; //和为正时累加 } else { b = arr[i - 1]; //否则将当前值赋给b bestx = i; } if (b > sum) { sum = b; besty = i; } } System.out.println("动态规划算法最优值:" + sum); System.out.println("最优解:" + bestx + "-->" + besty); } }
运行结果:
作为DP的经典案例,仔细体会DP的基本思想:保存已解决的子问题的答案,避免大量的重复计算。
本文出自 “闲庭信步、” 博客,请务必保留此出处http://macxiao.blog.51cto.com/9606147/1588001
求一数字序列的最大子段和(三种解法)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。