算法入门:最大子序列和的四种算法(Java)
最近再学习算法和数据结构,推荐一本书: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);
//
}
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);
//
}
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);
//
}
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);
//
}
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;
}
}
算法入门:最大子序列和的四种算法(Java)的更多相关文章
- K:求取数组中最大连续子序列和的四个算法
相关介绍: 求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...
- Android入门——电话拨号器和四种点击事件
相对于HelloWorld来说,电话拨号器也是Android的一个入门demo,从这个样例我们要理清楚做安卓项目的思路. 大体分为三步: 1.理解需求,理清思路 2.设计UI 3.代码实现 电话拨号器 ...
- 笔试算法题(53):四种基本排序方法的性能特征(Selection,Insertion,Bubble,Shell)
四种基本算法概述: 基本排序:选择,插入,冒泡,希尔.上述算法适用于小规模文件和特殊文件的排序,并不适合大规模随机排序的文件.前三种算法的执行时间与N2成正比,希尔算法的执行时间与N3/2(或更快)成 ...
- TCP控制拥塞的四种算法:慢开始,拥塞避免,快重传,快恢复
我们在开始假定: 1:数据是单方向传递,另一个窗口只发送确认. 2:接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定. 一:慢开始算法和拥塞避免算法 发送方会维持一个拥塞窗口,刚开始的 ...
- SPFA,dijskra,prime,topu四种算法的模板
////#include<stdio.h> ////#include<string.h> ////#include<queue> ////#include<a ...
- 第二章 Vue快速入门-- 17 v-for指令的四种使用方式
1.v-for循环普通数组 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- 洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 使用四种算法
洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 水题一道…… 题目描述 农民约翰的母牛总是产生最好的肋骨.你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们. ...
- Hash算法入门指南(聊点不一样的算法人生)
前言 很多人到现在为止都总是问我算法该怎么学啊,数据结构好难啊怎么的,学习难度被莫名的夸大了,其实不然.对于一个学计算机相关专业的人都知道,数据结构是大学的一门必修课,数据结构与算法是基础,却常常容易 ...
- 算法入门 - 基于动态数组的栈和队列(Java版本)
之前我们学习了动态数组的实现,接下来我们用它来实现两种数据结构--栈和队列.首先,我们先来看一下栈. 什么是栈? 栈是计算机的一种数据结构,它可以临时存储数据.那么它跟数组有何区别呢? 我们知道,在数 ...
随机推荐
- ReactiveX 学习笔记(22)使用 RxJS + Angular 进行 GUI 编程
课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...
- Object.create() vs new SomeFunction() in javascript
Object.create builds an object that inherits directly from the one passed as its first argument. Wit ...
- Android Spinner 设置setOnItemSelectedListener时,竟会默认触发一次事件!
当然是关闭这坑货了: //禁止OnItemSelectedListener默认自动调用一次 spinnerDutyPerson.setSelection(0, true); //放到TagContai ...
- office 安装
在 gaobo百度云下载安装包. 自定义安装,并在自定义界面选择安装路径. 破解:
- 用js控制 给一个input赋值之后,change事件不能捕获到,解决办法
你用js给input赋值后要调用change方法 下面是jquery的写法 $('input#3').val("50"); $('input#3').change(); 自己试试吧
- mongodb异常恢复
构造mongdb异常 启动mongodb,bash mongodb.sh #!/bin/bash pid_file=/var/run/mongodb/mongod.pid pid_dir=/var/r ...
- Selenium Java关闭浏览器
在学习selenium的过程中发现一个问题,各种博客/教程都是教人用selenium的quit()和close()方法关闭浏览器. 但这不是我要的结果.这两个方法的前提是,用webdriver打开浏览 ...
- Jenkin配置执行远程shell命令
转载自 http://www.cnblogs.com/parryyang/p/6261730.html 在利用jenkins进行集成化部署的时候,我们在部署生成的war包时,往往需要进行一些备份,或者 ...
- 373. Find K Pairs with Smallest Sums 找出求和和最小的k组数
[抄题]: You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. D ...
- 251. Flatten 2D Vector 平铺二维矩阵
[抄题]: Implement an iterator to flatten a 2d vector. Example: Input: 2d vector = [ [1,2], [3], [4,5,6 ...