最近再学习算法和数据结构,推荐一本书: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)的更多相关文章

  1. K:求取数组中最大连续子序列和的四个算法

    相关介绍:  求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...

  2. Android入门——电话拨号器和四种点击事件

    相对于HelloWorld来说,电话拨号器也是Android的一个入门demo,从这个样例我们要理清楚做安卓项目的思路. 大体分为三步: 1.理解需求,理清思路 2.设计UI 3.代码实现 电话拨号器 ...

  3. 笔试算法题(53):四种基本排序方法的性能特征(Selection,Insertion,Bubble,Shell)

    四种基本算法概述: 基本排序:选择,插入,冒泡,希尔.上述算法适用于小规模文件和特殊文件的排序,并不适合大规模随机排序的文件.前三种算法的执行时间与N2成正比,希尔算法的执行时间与N3/2(或更快)成 ...

  4. TCP控制拥塞的四种算法:慢开始,拥塞避免,快重传,快恢复

    我们在开始假定: 1:数据是单方向传递,另一个窗口只发送确认. 2:接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定. 一:慢开始算法和拥塞避免算法 发送方会维持一个拥塞窗口,刚开始的 ...

  5. SPFA,dijskra,prime,topu四种算法的模板

    ////#include<stdio.h> ////#include<string.h> ////#include<queue> ////#include<a ...

  6. 第二章 Vue快速入门-- 17 v-for指令的四种使用方式

    1.v-for循环普通数组 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  7. 洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 使用四种算法

    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 水题一道…… 题目描述 农民约翰的母牛总是产生最好的肋骨.你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们. ...

  8. Hash算法入门指南(聊点不一样的算法人生)

    前言 很多人到现在为止都总是问我算法该怎么学啊,数据结构好难啊怎么的,学习难度被莫名的夸大了,其实不然.对于一个学计算机相关专业的人都知道,数据结构是大学的一门必修课,数据结构与算法是基础,却常常容易 ...

  9. 算法入门 - 基于动态数组的栈和队列(Java版本)

    之前我们学习了动态数组的实现,接下来我们用它来实现两种数据结构--栈和队列.首先,我们先来看一下栈. 什么是栈? 栈是计算机的一种数据结构,它可以临时存储数据.那么它跟数组有何区别呢? 我们知道,在数 ...

随机推荐

  1. java中封装类(一)

    java中封装类共九个,分别是Boolean,Byte,Short,Integer,Long,Float,Double,Character,Void 其中Void对于使用者并无多大意义,也不可以构造任 ...

  2. MQTT协议

    MQTT(Message Queue Telemerty Transport)是一种二进制协议,主要用于服务器和那些低功耗的物联网设备(IoT)之间的通信. 它位于 TCP 协议的上层,除了提供发布- ...

  3. SSM商城项目(四)

    1. 学习计划 1.图片服务器 2.图片服务器安装 3.图片服务器的使用 4.图片上传功能 5.富文本编辑器的使用方法 6.商品添加功能实现 2. 图片服务器 1.存储空间可扩展. 2.提供一个统一的 ...

  4. springcloud流程图

    自己画的: 别人画的 别人画的2

  5. Shapley值的一个应用

    看书有这样一个问题,某互联网公司今天需要加班,需要编写一个500行的程序代码,产品经理找了三个程序员来完成.按照完成量发奖金:1号普通程序员独立能写100行,2号大神程序员独立能写125行,3号美女程 ...

  6. Lua 和 C++ 交互

    step1.搭建好vs和lua相交互的环境: 1.下载一个lua5.3的源码: 2.有Lua_lib.lib这个文件: 3.开始配置: 鼠标放在工程名那: 右键选属性: 把包含目录点开进行编辑: 地址 ...

  7. NSLog无法使用

    iOS/macos 中 #import<foundation/foundation.h> nslog不能用 如果项目中包含c/c++程序代码 将其后缀修改成.m .mm 将项目的build ...

  8. 129. Sum Root to Leaf Numbers pathsum路径求和

    [抄题]: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a ...

  9. [leetcode]24. Swap Nodes in Pairs交换节点对

    Given a linked list, swap every two adjacent nodes and return its head. You may not modify the value ...

  10. canvas(一) 基本线条绘制

    var dom = document.getElementById('canvasItem'), ctx = dom.getContext('2d'); //坐标位置默认基于 浏览器窗口(0,0),此 ...