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

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

分析:本题最初为2005年浙江大学计算机系的考研题的最后一道程序设计题,在2006年里包括google在内的很多知名公司都把本题当作面试题。由于本题在网络中广为流传,本题也顺利成为2006年程序员面试题中经典中的经典。

如果不考虑时间复杂度,我们可以枚举出所有子数组并求出他们的和。不过非常遗憾的是,由于长度为n的数组有O(n2)个子数组;而且求一个长度为n的数组的和的时间复杂度为O(n)。因此这种思路的时间是O(n3)。

很容易理解,当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。基于这样的思路,我们可以写出如下代码。

参考代码:

/
// Find the greatest sum of all sub-arrays
// Return value: if the input is valid, return true, otherwise return false
/
bool FindGreatestSumOfSubArray
(int *pData,           // an arrayunsigned int nLength, // the length of arrayint &nGreatestSum     // the greatest sum of all sub-arrays
)
{// if the input is invalid, return falseif((pData == NULL) || (nLength == 0))return false;int nCurSum = nGreatestSum = 0;for(unsigned int i = 0; i < nLength; ++i){nCurSum += pData[i];// if the current sum is negative, discard itif(nCurSum < 0)nCurSum = 0;// if a greater sum is found, update the greatest sumif(nCurSum > nGreatestSum)nGreatestSum = nCurSum;}// if all data are negative, find the greatest element in the arrayif(nGreatestSum == 0){nGreatestSum = pData[0];for(unsigned int i = 1; i < nLength; ++i){if(pData[i] > nGreatestSum)nGreatestSum = pData[i];}}return true;
} 

讨论:上述代码中有两点值得和大家讨论一下:

·         函数的返回值不是子数组和的最大值,而是一个判断输入是否有效的标志。如果函数返回值的是子数组和的最大值,那么当输入一个空指针是应该返回什么呢?返回0?那这个函数的用户怎么区分输入无效和子数组和的最大值刚好是0这两中情况呢?基于这个考虑,本人认为把子数组和的最大值以引用的方式放到参数列表中,同时让函数返回一个函数是否正常执行的标志。

·         输入有一类特殊情况需要特殊处理。当输入数组中所有整数都是负数时,子数组和的最大值就是数组中的最大元素。

本文已经收录到《剑指Offer——名企面试官精讲典型编程题》一书中,有改动,书中的分析讲解更加详细,讨论了这种方法和动态规划方法的联系。欢迎关注。在我的英文博客里也有这道题的讲解,

感兴趣的读者可以参考 http://codercareer.blogspot.com/2011/09/no-03-maximum-sum-of-all-sub-arrays.html。
            本题已被 九度Online Judge系统收录,欢迎读者移步到 http://ac.jobdu.com/hhtproblems.php在线测试自己的代码。

博主何海涛对本博客文章享有版权。网络转载请注明出处http://zhedahht.blog.163.com/。整理出版物请和作者联系。对解题思路有任何建议,欢迎在评论中告知,或者加我微博http://weibo.com/zhedahht或者http://t.163.com/zhedahht与我讨论。谢谢。

程序员面试题精选100题(03)-子数组的最大和[算法]相关推荐

  1. 程序员面试题精选100题(42)-旋转数组的最小元素[算法]

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的 ...

  2. 程序员面试题精选100题(57)-O(n)时间的排序[算法]

    题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间. 分析:排序是面试时经常被提及的一类题目,我们也熟悉其中很多种算法,诸如插入排序.归并 ...

  3. 程序员面试题精选100题(20)-最长公共子串[算法]

    题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串.注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中.请编写一个函数,输入两个字符串, ...

  4. 程序员面试题精选100题(44)-数值的整数次方[算法]

    题目:实现函数double Power(double base, int exponent),求base的exponent次方.不需要考虑溢出. 分析:这是一道看起来很简单的问题.可能有不少的人在看到 ...

  5. 程序员面试题精选100题(43)-n个骰子的点数[算法]

    题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S.输入n,打印出S的所有可能的值出现的概率. 分析:玩过麻将的都知道,骰子一共6个面,每个面上都有一个点数,对应的数字是1到 6之间的一个数字. ...

  6. 程序员面试题精选100题

    程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树   ...

  7. 程序员面试题精选100题:41-50解题报告

    程序员面试题精选100题(41)-把数组排成最小的数[算法]   题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32,  321},则输出这两个能 ...

  8. [程序员面试题精选100题]13.第一个只出现一次的字符

    [题目] 在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b. [分析] [代码] /********************************* * 日期:2013- ...

  9. 程序员面试题精选100题(51)-顺时针打印矩阵

    // 程序员面试题精选100题(51)-顺时针打印矩阵.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostre ...

最新文章

  1. linux定义LD_library,linux – CentOS /usr/local / lib系统范围内$LD_LIBRARY_PATH?
  2. 2转单通道 python_机器学习用Python—Python集成工具包Anaconda安装步骤
  3. php artisan 更新,Laravel 5:PHP Artisan迁移:刷新
  4. IOS 程序猿 UITbleView 篇
  5. 用Python画中国地图(二)
  6. 伪命题:我们来谈谈校招生起薪的问题,它对你来说重要吗?
  7. 1787: [Ahoi2008]Meet 紧急集合
  8. Node.js~在linux上的部署
  9. 互联网晚报 | 8月11日 星期三 | 苏炳添成为小米品牌代言人;联想企业购正式上线;中国电信A股IPO战略配售结果出炉...
  10. 03 实现不同基本数据类型之间的类型转换 0214
  11. 云计算实战系列二(Linux-用户管理)
  12. Cloudera Manager 和 CDH 4 终极安装
  13. 智能优化算法(源码)-海鸥优化算法(SOA)
  14. Anaconda中安装pygame
  15. 记录几个贴代码比较美观的网站
  16. Android MDM 参考资料
  17. [shell编程] 入门基础总结 (一) (一种豁然开朗的感觉)
  18. 网上邻居,详细教您如何打开win7网上邻居
  19. opencv-python控制笔记本摄像头
  20. 用友U9 BP不执行

热门文章

  1. 暴富、投机,金钱、欲望、人性,一个叫 Fomo3D的游戏正在刷新你的世界观
  2. 深度学习入门教程UFLDL学习实验笔记一:稀疏自编码器
  3. Debug Assert Failed 怎么办?
  4. Spring Cloud Alibaba源码 - 16 Nacos 注册中心源码解析
  5. APM - Prometheus监控系统初探
  6. 深入理解分布式技术 - 读写分离场景及注意事项解读
  7. 并发编程-22J.U.C组件拓展之Fork/Join框架
  8. Spring MVC-09循序渐进之文件上传(基于Apache Commons FileUpload)
  9. Oracle-临时表空间(组)解读
  10. java动态规划凑硬币问题,详解动态规划最少硬币找零问题--JavaScript实现