【每周至少一篇 160819】最大子序列和问题的四种求法_Java
来源:互联网 发布:毕业论文致谢 知乎 编辑:程序博客网 时间:2024/04/29 06:21
本问题的分析和设计是来自于数据结构与算法分析JAVA语言表述的第二章算法分析中分析,我将其实现,两位小伙伴提提意见。四个示例的时间复杂度由高到低分别是O(n3)、O(n2)、O(nlogn)以及O(N)。可以说不同的复杂度的算法代表着你理解该问题的深度。
原问题是:对于给定的(可能有负数)整数A1、A2、A3…An,求所有子序列中和最大的子序列的值。(同时,为了方便起见,当所有的数均是负数时,则最大子序列的和为0)。
算法一:选定遍历子序列的起点,在起点决定的基础上选定遍历子序列的重点,每次遍历中累加记得子序列的和并进行比较。
public static int maxSubSum1(int[] a){ int maxSum = 0; for(int i = 0; i < a.length; i++) for(int j = i; j < a.length; j++){ int thisSum = 0; for(int k = i; k <= j; k++) thisSum += a[k]; maxSum = thisSum > maxSum ? thisSum: maxSum; } return maxSum; }
算法二:与算法一的区别是:当子序列的起点不变时,子序列的和可以由前一个子序列的值加上添加的元素a[j]。整个算法还是需要遍历该数组的所有子序列,仅仅是将子序列的求和简化在线性时间内。
public static int maxSubSum2(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]; maxSum = thisSum > maxSum ? thisSum: maxSum; } } return maxSum; }
算法三:采用分治策略(divide and conquer)
public static int maxSubSum3(int[] a){ return maxSubRec(a, 0, a.length - 1); } private static int maxSubRec(int[] a, int left, int right) { // TODO 自动生成的方法存根 if(left == right) if(a[left] > 0) return a[left]; else return 0; int center = (right - left) / 2 + left; int maxLeftSum = maxSubRec(a, left, center); int maxrightSum = maxSubRec(a, center + 1, right); int maxLeftBorderSum = 0, leftBorderSum = 0; for(int i = center; i >= left; i--){ leftBorderSum += a[i]; maxLeftBorderSum = leftBorderSum > maxLeftBorderSum? leftBorderSum: maxLeftBorderSum; } int maxRightBorderSum = 0, rightBorderSum = 0; for(int i = center + 1; i <= right; i++){ rightBorderSum += a[i]; maxRightBorderSum = rightBorderSum > maxRightBorderSum? rightBorderSum: maxRightBorderSum; } int temp1 = maxLeftSum > maxrightSum? maxLeftSum: maxrightSum; int temp2 = maxLeftBorderSum + maxRightBorderSum; return temp1 > temp2? temp1: temp2; }
算法四:通过理解最大子序列的头部一定不是负数串,一次遍历就可以求出最大子字符串的值,但是这种方法不具有普遍的可分析性,不容易理解且不容易设计。该算法的时间复杂度是O(n)的。
public static int maxSubSum4(int[] a){ int 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; }
测试时所使用的main函数:
public class MaxSubSum { public static void main(String[] args){ int[] arry = {-2, 11, -4, 13, -5, -2}; System.out.println(maxSubSum1(arry)); System.out.println(maxSubSum2(arry)); System.out.println(maxSubSum3(arry)); System.out.println(maxSubSum4(arry)); }}
四种方法对应测试的数据均正确。
0 0
- 【每周至少一篇 160819】最大子序列和问题的四种求法_Java
- 最大子段和四种求法
- 最大子段和四种求法
- 【每周至少一篇 160727】简单的选择问题(select problem)_Java
- 最大子序列和问题的四种算法
- 【每周至少一篇 160811】函数对象_Java
- 最大连续子序列最大和的四种解法
- 【每周至少一篇 160811(上周补传)】泛型_Java
- 最大子序列问题的四种解法
- 连续子序列最大和问题的四种经典解答
- HDU1003 Max Sum 最大子序列和的问题【四种算法分析+实现】
- 最大子序列和的四种解法
- 求最大子序列和的四种方法
- 最大子序列和的四种算法
- 最大子序列和的四种算法之讲解
- 最大子序列和的四种不同复杂度实现
- 最大子序列和的四种不同复杂度实现
- 最大的子序列和的问题
- 输入一个字符串,内有数字和非数字字符。
- 深度学习笔记5:池化层的实现
- Javascript基础-介绍、实现、输出
- BZOJ1635 [Usaco2007 Jan]Tallest Cow 最高的牛 数列差分
- oracle执行了shutdown某个实例之后,如何重新启动
- 【每周至少一篇 160819】最大子序列和问题的四种求法_Java
- Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程
- zookeeper运维管理
- hdu 5867 (一到一千的模拟题)
- clipBoardEvent, execCommand等粘贴板相关研究
- Cracer渗透测试网络培训第一期
- 早上学了一下java的随机数,下面把代码复制一下
- canvas的save与restore方法的作用
- 树上路径