一、题目:连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18。

  这个题目在我去年参加校园招聘时,某公司的二面采用了机试,而题目刚好就是这道题。一般看到这道题目就会想到枚举出数组的所有子数组并求出它们的和。一个长度为n的数组,总共有n(n+1)/2个子数组。计算出所有子数组的和,最快也需要O(n2)的时间。但是最直观的方法不会是最优的解法,因此面试官不会满意这样的思路。

二、解题思路

2.1 核心步骤

  Step1.从头到尾逐个累加数组中的每个数字,初始化和为0;(nCurrSum=0,nGreatestNum=int.MinValue)

  Step2.首先加上第一个数字,从第二个数字开始累加,依次将累加和保存到一个临时变量(nCurrSum)中;

  Step3.如果当前累加和(nCurrSum)小于0,那抛弃前面的子数组和,从下一个数字开始重新累加;相反,则将当前累加和(nCurrSum)与返回累加和(nGreatestNum)进行比较,如果nCurrSum>nGreatestNum,则更新nGreatestNum。

  这样比较进行一次遍历之后,就可以得到最终的最大累加和,时间复杂度是O(n)。下图展示了计算数组{1,-2,3,10,-4,7,2,-5}中子数组的最大和的过程:

2.2 代码实现

    /// <summary>
/// 计算连续子数组的最大和
/// </summary>
public static int FindGreatestSumOfSubArray(int[] array, out bool isValidInput)
{
if (array == null || array.Length <= )
{
isValidInput = false;
return ;
} isValidInput = true; int currSum = ;
int greatestSum = int.MinValue; for (int i = ; i < array.Length; i++)
{
if(currSum <= )
{
currSum = array[i];
}
else
{
currSum += array[i];
} if (currSum > greatestSum)
{
greatestSum = currSum;
}
} return greatestSum;
}

三、单元测试

3.1 测试用例

    // 1, -2, 3, 10, -4, 7, 2, -5
[TestMethod]
public void GetGreatestNumTest1()
{
int[] data = { , -, , , -, , , - };
bool isValid = true;
int actual = SubArrayHelper.FindGreatestSumOfSubArray(data, out isValid);
if (isValid)
{
Assert.AreEqual(actual, );
}
else
{
Assert.AreEqual(isValid, false);
}
} // 所有数字都是负数
// -2, -8, -1, -5, -9
[TestMethod]
public void GetGreatestNumTest2()
{
int[] data = { -, -, -, -, - };
bool isValid = true;
int actual = SubArrayHelper.FindGreatestSumOfSubArray(data, out isValid);
if (isValid)
{
Assert.AreEqual(actual, -);
}
else
{
Assert.AreEqual(isValid, false);
}
} // 所有数字都是正数
// 2, 8, 1, 5, 9
[TestMethod]
public void GetGreatestNumTest3()
{
int[] data = { , , , , };
bool isValid = true;
int actual = SubArrayHelper.FindGreatestSumOfSubArray(data, out isValid);
if (isValid)
{
Assert.AreEqual(actual, );
}
else
{
Assert.AreEqual(isValid, false);
}
} // 无效输入
[TestMethod]
public void GetGreatestNumTest4()
{
bool isValid = true;
int actual = SubArrayHelper.FindGreatestSumOfSubArray(null, out isValid);
if (isValid)
{
Assert.AreEqual(actual, );
}
else
{
Assert.AreEqual(isValid, false);
}
}

3.2 测试结果

  (1)测试用例通过情况

  (2)代码覆盖率

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

剑指Offer面试题:28.连续子数组的最大和的更多相关文章

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

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

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

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

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

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

  4. 【剑指Offer】30、连续子数组的最大和

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

  5. 剑指offer三十之连续子数组的最大和

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

  6. 剑指offer(30)连续子数组和的最大值

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

  7. 【剑指offer】Q31:连续子数组的组大和

    简短的分析见:http://blog.csdn.net/shiquxinkong/article/details/17934747 def FindGreatestSumOfSubArray(arra ...

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

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

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

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

随机推荐

  1. C 标准库系列之float.h

    float.h 内部主要包含了一系列的浮点数宏.指明可移植程序必要的常量:浮点数格式一般为Spxbe;其中S表示+-:p表示底数.b表示基数如2.8.10.16等进制,e为指数标识E或e: 在一般情况 ...

  2. Kafka、RabbitMQ、RocketMQ消息中间件的对比 —— 消息发送性能-转自阿里中间件

    引言 分布式系统中,我们广泛运用消息中间件进行系统间的数据交换,便于异步解耦.现在开源的消息中间件有很多,前段时间我们自家的产品 RocketMQ (MetaQ的内核) 也顺利开源,得到大家的关注. ...

  3. 【Hawk】入门教程(1)——从URL开始

    入门教程(1)--从URL开始 首先感谢辛苦的沙漠君 先把沙漠君的教程载过来:)可以先看一遍 Hawk-数据抓取工具:简明教程 Hawk 数据抓取工具 使用说明(二) 20分钟无编程抓取大众点评17万 ...

  4. 安卓智能POS终端手持机PDA应用仓库出入库,移库,盘点,销售开单系统

    随着移动互联网的兴起,目前仓储管理所面临的的问题可以迎刃而解,WMS仓库系统解决方案通过智能终端扫描条码技术应用解决了工作量大导致工作效率不高,以及数据实时传输等问题,该方案主要提供仓库出入库,移库, ...

  5. 转:Delphi 6 实用函数

    来自: daocaoren0824, 时间: -- ::, ID: 再给你一份 程序员实用函数 {▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎▎} {▎ ▎} {▎ 大 ...

  6. Android端简易蓝牙聊天通讯App(原创)

    欢迎转载,但请注明出处!谢谢.http://www.cnblogs.com/weizhxa/p/5792775.html 最近公司在做一个蓝牙串口通讯的App,有一个固定的蓝牙设备,需要实现手机连接相 ...

  7. 页面制作之HTML

    标签 常用属性 id class style title - <a href ="/" title="收藏">收藏</a>(用于hove ...

  8. 原生JS 年月日、省市区 三级联动

    这个算生日日期,因为是从100年前的到现年. <select id="sel_year"></select> <select id="sel ...

  9. 【BZOJ】4001: [TJOI2015]概率论

    题意 求节点数为\(n\)的有根树期望的叶子结点数.(\(n \le 10^9\)) 分析 神题就打表找规律.. 题解 方案数就是卡特兰数,$h_0=1, h_n = \sum_{i=0}^{n-1} ...

  10. Javascript 面向对象编程(一):封装

    Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类). 那么,如果 ...