题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求全部子数组的和的最大值。要求时间复杂度为O(n)。


样例说明:

比如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5}。和最大的子数组为{3, 10, -4, 7, 2}。因此输出为该子数组的和18 。

解题思路:

解法一:举例分析数组的规律。

我们试着从头到尾逐个累加演示样例数组中的每一个数字。

初始化和为0。第一步加上第一个数字1。 此时和为1。

接下来第二步加上数字-2,和就变成了-1。第三步刷上数字3。我们注意到因为此前累计的和是-1 ,小于0,那假设用-1 加上3 ,得到的和是2 。 比3 本身还小。也就是说从第一个数字開始的子数组的和会小于从第三个数字開始的子数组的和。

因此我们不用考虑从第一个数字開始的子数组,之前累计的和也被抛弃。

我们从第三个数字又一次開始累加,此时得到的和是3 。

接下来第四步加10,得到和为13 。第五步加上-4, 和为9。我们发现因为-4 是一个负数,因此累加-4 之后得到的和比原来的和还要小。因此我们要把之前得到的和13 保存下来。它有可能是最大的子数组的和。第六步加上数字.7。9 加7 的结果是16。此时和比之前最大的和13 还要大, 把最大的子数组的和由13更新为16。第七步加上2,累加得到的和为18。同一时候我们也要更新最大子数组的和。

第八步加上最后一个数字-5,因为得到的和为13 ,小于此前最大的和18,因此终于最大的子数组的和为18 。相应的子数组是{3, 10, -4, 7, 2}。

解法二: 应用动态归划法。

能够用动态规划的思想来分析这个问题。假设用函数f(i)表示以第i个数字结尾的子数组的最大和。那么我们须要求出max[f(i)],当中0 <= i < n。我们可用例如以下边归公式求f(i):

这个公式的意义:当以第i-1 个数字结尾的子数组中全部数字的和小于0时。假设把这个负数与第i个数累加。得到的结果比第i个数字本身还要小,所以这样的情况下以第i个数字结尾的子数组就是第i个数字本身。假设以第i-1 个数字结尾的子数组中全部数字的和大于0 ,与第i 个数字累加就得到以第i个数字结尾的子数组中全部数字的和。

本题採用第一种实现方式

代码实现:

public class Test31 {
/**
* 题目2 输入一个整型数组,数组里有正数也有负数。数组中一个或连
* 续的多个整数组成一个子数组。求全部子数组的和的最大值。 要求时间复杂度为O(n)。
*
* @param arr 输入数组
* @return 最大的连续子数组和
*/
public static int findGreatestSumOfSubArray(int[] arr) {
// 參数校验
if (arr == null || arr.length < 1) {
throw new IllegalArgumentException("Array must contain an element");
} // 记录最大的子数组和,開始时是最小的整数
int max = Integer.MIN_VALUE;
// 当前的和
int curMax = 0;
// 数组遍历
for (int i : arr) {
// 假设当前和小于等于0,就又一次设置当前和
if (curMax <= 0) {
curMax = i;
}
// 假设当前和大于0,累加当前和
else {
curMax += i;
} // 更新记录到的最在的子数组和
if (max < curMax) {
max = curMax;
}
} return max;
} public static void main(String[] args) {
int[] data = {1, -2, 3, 10, -4, 7, 2, -5};
int[] data2 = {-2, -8, -1, -5, -9};
int[] data3 = {2, 8, 1, 5, 9}; System.out.println(findGreatestSumOfSubArray(data));
System.out.println(findGreatestSumOfSubArray(data2));
System.out.println(findGreatestSumOfSubArray(data3));
}
}

执行结果:

【剑指Offer学习】【面试题31:连续子数组的最大和】的更多相关文章

  1. 【剑指offer】面试题 42. 连续子数组的最大和

    面试题 42. 连续子数组的最大和 NowCoder 题目描述 输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值. 示例: 输入: [-2,1 ...

  2. 《剑指offer》面试题42. 连续子数组的最大和

    问题描述 输入一个整型数组,数组里有正数也有负数.数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求时间复杂度为O(n). 示例1: 输入: nums = [-2,1,-3,4 ...

  3. 剑指offer面试题31连续子数组的最大和

    一.题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果 ...

  4. 剑指 offer 面试题31 连续子数组的最大和(动态规划)

    求连续子数组的最大和 题目描述 给定一个整形数组,有正数也有负数,数组中连续一个或多个组成一个子数组,求所有子数组的和的最大值,要求时间复杂度为O(n); 测试用例 给定数组 {1,-2,3,10,- ...

  5. 剑指Offer:面试题31——连续子数组的最大和(java实现)

    问题描述 : 输入一个整数数组,数组里面有正数也有负数.数组中一个或连续几个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为O(n) 思路1:常规解法,不知道怎么描述了.. 代码: bo ...

  6. leetcode面试题42. 连续子数组的最大和

      总结一道leetcode上的高频题,反反复复遇到了好多次,特别适合作为一道动态规划入门题,本文将详细的从读题开始,介绍解题思路. 题目描述示例动态规划分析代码结果 题目   面试题42. 连续子数 ...

  7. (剑指Offer)面试题31:连续子数组的最大和

    题目: 输入一个整型数组,数组里有正数也有负数,数组中一个或连续多个整数组成一个子数组,求所有子数组的和的最大值.要求时间复杂度为O(n) 思路: 1.数组累加 从头到尾逐个累加数组中的每个数字,当累 ...

  8. 【剑指offer】面试题31:连续子数组的最大和

    题目: 在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2, ...

  9. 【剑指offer】面试题 31. 栈的压入、弹出序列

    面试题 31. 栈的压入.弹出序列 NowCoder LeetCode 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如 ...

  10. 《剑指offer》面试题31. 栈的压入、弹出序列

    问题描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2 ...

随机推荐

  1. 输入和输出(IO流)

    File类的常用方法: File对象的创建和部分方法使用: File file =new File("file\\我是文本.txt"); System.out.println(&q ...

  2. Mybatis输入输出映射_动态sql_关联关系(一对一、一对多、多对多)

    Mybatis输入输出映射_动态sql_关联关系(一对一.一对多.多对多)输入输出映射parameterType完成输入映射parameterType可以传入的参数有,基本数据类型(根据id查询用户的 ...

  3. Python应该怎样实现快速入门?

    作为一名Python爱好者,我也想跟大家分享分享我自学Python的一些小经验.搬来你的小板凳,听听看吧.也许,你会很有收获,也许你也走上了自学Python的不归路.开讲啦~ 首先,你要有自信心,要明 ...

  4. pymouse pykeyboard

    import time from pymouse import PyMouse from pykeyboard import PyKeyboard import re import win32clip ...

  5. winfrom 多线程 并发 和定时任务

    static void Main(string[] args) { //多个线程修改同一个值,使用lock锁解决并发 for (int i = 0; i < 4; i++) { Task.Fac ...

  6. gulp(1) 的使用

    1.安装node.js 2.全局安装gulp.js npm install gulp -g 3.在项目本地根目录再安装(通过黑窗口安装)npm install --save-dev gulp/ 或者 ...

  7. c++基础_特殊回文数

    #include <iostream> using namespace std; int main(){ int n; cin>>n; ;i<;i++){ int tem ...

  8. python 安装模块 更新模块

    #显示模块pip list #显示过期模块pip list --outdated #安装模块pip install xxx #升级模块pip install --upgrade xxx

  9. 版本控制git之五-标签管理 tags 标签 代码版本 如: v1.0

      版本控制git之五-标签管理 打标签 像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要. 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等). ...

  10. 使用js生成条形码以及二维码

    一.用js生成条形码这种业务场景不是很常见的,最近刚好又接到这种需求 Google一下,发现github还真有这方面的轮子,感谢github,省去了我们很多造轮子的过程, 好了言归正传,首先引入jsb ...