博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【面试】求数组子序列的最大和
阅读量:5172 次
发布时间:2019-06-13

本文共 1973 字,大约阅读时间需要 6 分钟。

 原文地址:

一、问题描述

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

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

第一次遇到这道题是参加x迅的笔试。题目中给出了两种解法,让填空。

二、简单解

拿到这道题,如果不考虑性能和复杂度,最简单的方法就是穷举。穷举出所有的子数组,并求出他们的和,返回最大值。不过,复杂度为O(n3),不符合题目的要求(复杂度On)

int max_sum(int *arr, int len){      int max, sum;        for(int i = 0; i < len; i++) {          for(int j = i; j < len; j++) {              sum = 0;              for(int k = i; k <= j; k++) {                  sum = sum + arr[k];                  if(sum > max) {                      max = sum;                  }              }          }      }        if(max == 0) {          return max(arr, len);      }      return max;  }

 

三、复杂度为N2的解

 

观察上面的代码,我们使用了3个for循环。其中最内侧的for循环主要是控制每个字序列的长度,由于我们在计算的过程中,已经保存了当前最大字序列和,字序列的长度N对我们来说意义不大,因此完全可以撤消最内侧的循环。只按每个字序列起始位置来计算最大和。这样得到一个复杂度为N2的解。

int max_sum2(int *arr, int len){      int sum, max = 0;        for(int i = 0; i < len; i++) {          sum = 0;          for(int j = i; j < len; j++) {              sum = sum + arr[j];              if(max < sum) {                  max = sum;              }          }      }        if(max == 0) {          return max(arr, len);      }            return max;  }

 

四、更低复杂度的探索

 
至此,我们已经得到一个复杂度为N
2的解法。那么有没有更低复杂度的算法呢?在N
2的算法中,我们遍历了从0到len-1开始的字序列,求出每种情况下得到的最大字序列和。那么我们有没有可能去掉这个循环呢?考虑使用
的思想,记max_sum[i]为从0到i的子序列的最大和,那么可以得到递推式:
 
if max_sum[i] > 0    then           if arr[i+1] > 0           then max_sum[i+1] = max_sum[i] + arr[i+1];    else           max_sum[i+1] = max(0, arr[i+1])

利用这种思路得到一个线性时间的解答:

int max_sum3(int *arr, int len) {      int sum, max;        max = sum = 0;      for(int i = 0; i < len; i++) {          sum += arr[i];          if(sum < 0) {              sum = 0;          }            if(sum > max){              max = sum;          }      }        if(max == 0) {          return max(arr, len);      }      return max;  }

至此,我们得到一个时间复杂度On,空间复杂度O1的解。

转载于:https://www.cnblogs.com/zhousan/p/3140846.html

你可能感兴趣的文章
【转】TCP是流传输协议,UDP是包传输协议
查看>>
Javascript基础1
查看>>
SNF快速开发平台2019-权限管理模型实践-权限都在这里
查看>>
Shell脚本语言与编译型语言的差异
查看>>
错误:linker command failed with exit code 1 (use -v to see invocation)
查看>>
12.10 Nginx访问日志 12.11 Nginx日志切割 12.12 静态文件不记录日志和过期时间
查看>>
css Reset
查看>>
js正则表达式大全
查看>>
多线程 NSThread GCD
查看>>
ZevenOS 5.0 发布,德国人的 Linux 发行
查看>>
pictureBox绑定Base64字符串
查看>>
postgre索引
查看>>
哈夫曼编码译码系统(c/c++)
查看>>
Hbase性能调优(一)
查看>>
5自由落体运动
查看>>
python数据处理的常用操作
查看>>
一个简单的投票功能
查看>>
Linux服务器压测/拷机软件收集
查看>>
Linux系统备份还原工具1(DD)
查看>>
Ubuntu 16.04安装网络流量监控工具Netspeed(附带10款最佳的指示器工具)
查看>>