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

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

如果没有O(n)这条要求,那么我们可以通过枚举法,枚举出所有的子数组,然后分别对每个子数组求和,这个规模将达到O(n3).

O(n)算法的基本思想是依次扫描数组中所有的数,用一个变量nGreatestSum来保存当前所有子数组和中最大的那个值,用另外一个变量nCurSum记录扫描到第i个数的时候,所有子数组的最大值,一旦发现nCurSum的值为负数,则将之前的子数组全部抛弃,所以nCurSum置为0,直到nCurSum的值大于nGreatestSum的值才更新nGreatestSum为nCurSum的值,当整个数组扫描完毕的时候,所有子数组的最大值也就算出来了。

bool FindGreatestSumOfSubArray(
      int *pData,           // 要扫描的数组
      unsigned int nLength, // 数组长度
      int &nGreatestSum     // 子数组的最大值
)
{
     
      if((pData == NULL) || (nLength == 0))
            return false;

int nCurSum = nGreatestSum = 0;
      for(unsigned int i = 0; i < nLength; ++i)
      {
            nCurSum += pData[i];

// 如果当前最大值为负数,抛弃之
            if(nCurSum < 0)
                  nCurSum = 0;

//一旦发现最大值了,更新最大值记录
            if(nCurSum > nGreatestSum)
                  nGreatestSum = nCurSum;

}

// 所有值为负数的时候,最大值应该是所有负数中最大的那个值
      if(nGreatestSum == 0)
      {
            nGreatestSum = pData[0];
            for(unsigned int i = 1; i < nLength; ++i)
            {
                  if(pData[i] > nGreatestSum)
                        nGreatestSum = pData[i];
            }
      }
      return true;
}

一些思考:有些读者可能会举类似这样一个反例

10 -11 5

会认为前面两个数的和为 -1 应该抛弃前面两个数,而此数组中最大子数组的值为10,如果读者仔细斟酌一下"抛弃"这两个字就会不难发现,抛弃只是更新了nCurSum的值的大小,而想要更新nGreatestSum的大小的时候,必须满足nCurSum<nGreatestSum,因此,nGreatestSum的值依然没变,依然是10

何海涛算法面试题感悟之三:子数组…相关推荐

  1. 何海涛算法面试题感悟之一:将二叉…

    题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树                                     ...

  2. 何海涛算法面试题感悟之五:查找最…

    题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 一个简单的方法就是排序,先将这n个数按从大到小排序,最快需要O(nlog ...

  3. 何海涛算法面试题感悟之二:设计包…

    题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1) 如果没有min,该栈可以很轻松地构造出来,现在添加了一个min功能,首 ...

  4. 何海涛算法面试题感悟之四:二元树…

    题目:输入一个整数和一棵二元树.从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径.打印出和与输入整数相等的所有路径. 例如输入整数22和如下二元树 10                 ...

  5. 何海涛算法面试题感悟之六:二元查…

    题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8   ...

  6. 何海涛算法面试题感悟之九:寻找链…

    题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: struct ListNode {       int       m_nKey;      ...

  7. prim算法_历时两月,终拿字节跳动offer,算法面试题分享「带答案」

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享! Java架构筑基​zhuanlan.zhihu.com Java架构筑基--专注于Java技术的研究与分享! 后续文章 ...

  8. java面笔试_java笔试手写算法面试题大全含答案

    java笔试手写算法面试题大全含答案 1.统计一篇英文文章单词个数. public class WordCounting { public static void main(String[] args ...

  9. 66 道前端算法面试题附思路分析助你查漏补缺

    大家好,我是漫步. 今天来分享一篇干货,前端关于算法的分析不多,下文列举了66道前端算法面试题,希望对你有所帮助. 作者:Eno_Yao https://segmentfault.com/a/1190 ...

最新文章

  1. java影院购票系统开题报告,开题报告-网上电影院购票系统的设计与实现.doc
  2. 猛然发现,已经第100篇随笔了
  3. exfat最佳单元大小_双动圈四喇叭单元的头戴式耳机,DACOM HF002上手体验
  4. 042_前端规范 2021-06-03
  5. 关于linux开机自启
  6. java生成mib文件_【snmp】使用MIB Builder生成MIB文件
  7. 阿拉伯数字转换大写例如:120转一百二十
  8. 【LwM2M】LwM2M协议官方文档
  9. 后端开发工程师的工作流程是怎样的
  10. 人月神话(二)——为什么巴比伦塔会失败
  11. Component xxx does not have a method xxx to handle event xxx
  12. 0x0000004e蓝屏代码解决教程
  13. 扫描工具nmap、ncat
  14. 扫描版pdf重排 linux,【Kindle Pdf Viewer中文安装教程】支持扫描版PDF重排及其他主流文件格式...
  15. stm32f103移植ucosIII系统
  16. 《 QT5.9 c++ 开发指南》各种常见图表的绘制(一个例子让你不再担心表图的绘制)
  17. 定风波/三月七日——苏轼
  18. 【vijos】1006 晴天小猪历险记之Hill(dijkstra)
  19. python类中最大的_python类的学习笔记(一)
  20. AdEx、Ardor、Bluzelle项目评级更新 | TokenInsight

热门文章

  1. vbscript能干什么
  2. 羊皮卷的故事-第八章-羊皮卷之一
  3. Vue3.0 凉凉了?Vue 最黑暗的一天!
  4. 字是人的脸,可我就是写不好
  5. mysql 聚簇索引与非聚簇索引
  6. 鲁大师12月新机性能榜:跑分116万,小米12 Pro夺冠
  7. LeetCode Algorithm 225. 用队列实现栈
  8. 无胁科技-TVD每日漏洞情报-2022-11-29
  9. CAD 学习笔记 Mac
  10. 【腾讯快直播】IJK播放器改造:传输层低延迟播放优化