算法入门:最大子序列和的四种算法(Java)
2018-06-18 02:28:36来源:未知 阅读 ()
最近再学习算法和数据结构,推荐一本书:Data structures and Algorithm analysis in Java 3rd
以下的四种算法出自本书

四种最大子序列和的算法:
问题描述
给定(可能有负数)整数a(1)、a(2)、……a(n),求 a(1)+a(2)+……+a(j)的最大值。为方便起见,若所有的整数为负数,则最大子序列和为0.
也就是:在一系列整数中,找出连续的若干个整数,这若干个整数之和 最大。
第一种:穷举所有可能,由于嵌套三层for循环,运行时间O(N^3)
package demo1; public class Demo1 { public static void main(String[] args) { int[] a = { -2, 4, -3, 5, 7, -1, 8, 1 }; int max = maxSubSum1(a); System.out.println(max); // 21 } private 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]; } if (thisSum > maxSum) { maxSum = thisSum; } } } return maxSum; } }
第二种:在第一种的基础上简化,撤除一层for循环,运行时间O(N^2)
package demo1; public class Demo2 { public static void main(String[] args) { int[] a = { -2, 4, -3, 5, 7, -1, 8, 1 }; int max = maxSubSum2(a); System.out.println(max); // 21 } private 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]; if (thisSum > maxSum) { maxSum = thisSum; } } } return maxSum; } }
这两种算法本质上类似,后边两种算法将大大提升效率
第三种:这里求解的思想完全改变了,时间仅仅O(NlogN)
它把这一组数分成前一半和后一半,再分别针对这两部分处理(分治法)
显而易见:最大子序列和必定是前一段或者后一段或者前后中间这一段这三者之一,再利用递归循环计算
注:代码是越短越好,但是算法未必,这种算法也许很长,但是相比前两种算法它更优秀
代码如下:
package demo1; public class Demo3 { public static void main(String[] args) { int[] a = { -2, 4, -3, 5, 7, -1, 8, 1 }; int max = maxSubSum3(a); System.out.println(max); // 21 } private static int maxSubSum3(int[] a) { // 递归初始化参数 return maxSumRec(a, 0, a.length - 1); } private static int 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; int maxLeftSum = maxSumRec(a, left, center); int maxRightSum = maxSumRec(a, center + 1, right); // 左端处理 int maxLeftBorderSum = 0; int leftBoarderSum = 0; for (int i = center; i >= left; i--) { leftBoarderSum += a[i]; if (leftBoarderSum > maxLeftBorderSum) { maxLeftBorderSum = leftBoarderSum; } } // 右端处理 int maxRightBoarderSum = 0; int rightBoarderSum = 0; for (int i = center + 1; i <= right; i++) { rightBoarderSum += a[i]; if (rightBoarderSum > maxRightBoarderSum) { maxRightBoarderSum = rightBoarderSum; } } // 返回最大值 return Math.max(Math.max(maxLeftSum, maxRightSum), maxLeftBorderSum + maxRightBoarderSum); } }
第四种方式:最优秀的算法:O(N)
这种方式很巧妙,不易想出,需要有很深编程技术的程序员才能想到
package demo1; public class Demo4 { public static void main(String[] args) { int[] a = { -2, 4, -3, 5, 7, -1, 8, 1 }; int max = maxSubSum4(a); System.out.println(max); // 21 } private static int maxSubSum4(int[] a) { int maxSum = 0; int thisSum = 0; for (int i = 0; i < a.length; i++) { thisSum += a[i]; if (thisSum > maxSum) { maxSum = thisSum; } else if (thisSum < 0) { thisSum = 0; } return maxSum; } return 0; } }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Java打包商用化软件
下一篇:Java:构造代码块,静态代码块
- DES/3DES/AES 三种对称加密算法实现 2020-06-11
- logstash系列-入门整理 2020-06-10
- Java 入门教程 2020-06-09
- RocketMQ4.4 入门进阶+实战 2020-06-08
- 因为 MongoDB 没入门,我丢了一份实习工作 2020-06-07
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
