算法入门:最大子序列和的四种算法(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版本)
之前我们学习了动态数组的实现,接下来我们用它来实现两种数据结构--栈和队列.首先,我们先来看一下栈. 什么是栈? 栈是计算机的一种数据结构,它可以临时存储数据.那么它跟数组有何区别呢? 我们知道,在数 ...
随机推荐
- MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结
MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...
- iOS app审核被拒申诉
提交申诉理由之后不需要点击“提交审核”按钮,否则按照重新提交算,需要重新排队,且申诉会不起作用.
- c#: Label控件加入AutoHeight属性
此功能在界面布局中颇为实用,录代码以记之: public class LabelEx : Label { private bool autoHeight = true; [DefaultValue(t ...
- [leetcode]10. Regular Expression Matching正则表达式的匹配
Given an input string (s) and a pattern (p), implement regular expression matching with support for ...
- kalman滤波(二)---扩展kalman滤波[EKF]的推导
一.状态估计的解释 我们知道每个方程都受噪声的影响,这里把位姿x和路标y看成服从某种概率分布的随机变量.因此我们关心的问题就变成了:当我们已知某些运动数据u和观测数据z时,如何确定状态量x,y的分布? ...
- centos 7 命令行模式和桌面版之间的切换
CentOS7图形界面与命令行界面切换 在图形界面使用 ctrl+alt+F2切换到dos界面 dos界面 ctrl+alt+F2切换回图形界面 在命令上 输入 init 命令 切换到dos界面 输入 ...
- IIS7发布asp.net mvc提示404.0
https://support.microsoft.com/zh-cn/help/980368/a-update-is-available-that-enables-certain-iis-7-0-o ...
- mybatis进阶--一对多查询
首先,我们还是先给出一个需求:根据订单id查询订单明细——我们知道,一个订单里面可以有多个订单的明细(需求不明确的同学,请留言或者去淘宝网上的订单处点一下就知道了).这个时候,一个订单,对应多个订单的 ...
- BeanUtils.copyProperties的简单示例
一.新建测试实体 1.UserA package com.dechy.hebswj.test; public class UserA { private String a; private Strin ...
- 为什么Firefox在SSH上这么慢?
为什么Firefox在SSH上这么慢? Modified on: Fri, 13 Jul 2018 18:37:30 +0800 我尝试使用 通过SSH启动Firefox ssh -X user@ho ...