python如何求数组连续最大和的示例代码


Posted in Python onFebruary 04, 2020

题目描述:

一个有 n 个元素的数组,这 n 个元素既可以是正数也可以是负数,数组中连续的一个或多个元素可以组成一个连续的子数组,一个数组可能有多个这种连续的子数组,求子数组的最大值。例如,对于数组 [1,-2,4,8,-4,7,-1,-5] 而言,其最大和的子数组为 [4,8,-4,7],最大值为 15。

方法:

  • 蛮力法
  • 重复利用已经计算的子数组和
  • 动态规划
  • 优化的动态规划

1.蛮力法

找出所有的子数组,然后求出子数组的和,在所有子数组的和中取最大值。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/29 21:59
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
def maxSubArrSum(arr):
  if arr == None or len(arr) <= 0:
    print('参数不合理!')
    return
  thisSum = 0
  maxSum = 0
  i = 0
  while i < len(arr):
    j = i
    while j < len(arr):# j 控制连续子数组包含的元素个数
      thisSum = 0
      k = i # k 表示连续子数组开始的下标
      while k < j:
        thisSum += arr[k]
        k += 1
      if thisSum > maxSum:
        maxSum = thisSum
      j += 1
    i += 1
  return maxSum


if __name__ == '__main__':
  arr = [1, -2, 4, 8, -4, 7, -1, -5]
  print('1 max sub array sum:', maxSubArrSum(arr))

结果:

python如何求数组连续最大和的示例代码

算法性能分析:
这种方法的时间复杂度为O(n3);

2.重复利用已经计算的子数组和

由于 sum[i,j] = sum[i,j-1] + arr[j],在计算 sum[i,j] 的时候可以使用前面已计算出的 sum[i,j-1] 而不需要重新计算,采用这种方法可以省去计算 sum[i,j-1] 的时间,从而提高效率。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/30 10:53
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
def maxSubArrSum(arr):
  if arr == None or len(arr) <= 0:
    print('参数不合理!')
    return
  maxSum = -2 ** 31
  i = 0
  while i < len(arr): # i: 0~7
    sums = 0
    j = i
    while j < len(arr): # j: 0~7
      sums += arr[j] # sums 重复利用
      if sums > maxSum: # 每加一次就判断一次
        maxSum = sums
      j += 1
    i += 1
  return maxSum


if __name__ == '__main__':
  arr = [1, -2, 4, 8, -4, 7, -1, -5]
  print('2 max sub array sum:', maxSubArrSum(arr))

结果:

python如何求数组连续最大和的示例代码

算法性能分析:
使用了双重循环,时间复杂度为O(n2);

3.动态规划

首先可以根据数组最后一个元素 arr[n-1] 与最大子数组的关系分为以下三种情况讨论:
(包含或不包含,包含的话肯定以最后一个元素结尾;不包含的话,或者最后一个元素单独构成最大子数组,或者转换为求 arr[1…n-2] 的最大子数组)
(1) 最大子数组包含 arr[n-1],即最大子数组以 arr[n-1] 结尾;
(2) arr[n-1] 单独构成最大子数组;
(3) 最大子数组不包含 arr[n-1],那么求 arr[1…n-1] 的最大子数组可以转换为求 arr[1…n-2] 的最大子数组。
所以有:

python如何求数组连续最大和的示例代码

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/30 11:19
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
def maxSubArrSum(arr):
  if arr == None or len(arr) <= 0:
    print('参数不合理!')
    return
  n = len(arr)
  End = [None] * n # End[i] 表示包含 arr[i] 的最大子数组和
  All = [None] * n # All[i] 表示最大子数组和
  End[n - 1] = arr[n - 1]
  All[n - 1] = arr[n - 1]
  End[0] = All[0] = arr[0]
  i = 1
  while i < n:
    End[i] = max(End[i - 1] + arr[i], arr[i]) # i=1时若arr[0]<0,则从arr[1]重新开始
    All[i] = max(End[i], All[i - 1])
    i += 1
  return All[n - 1]


if __name__ == '__main__':
  arr = [1, -2, 4, 8, -4, 7, -1, -5]
  print('3 max sub array sum:', maxSubArrSum(arr))

结果:

python如何求数组连续最大和的示例代码

算法性能分析:
时间复杂度为O(n);
由于额外申请了两个数组,所以空间复杂度为O(n);

4.优化的动态规划

方法3中每次其实只用到了 End[i-1] 与 All[i-1] ,而不是整个数组中的值,所以可以定义两个变量来保存 End[i-1] 与 All[i-1] 的值,并且可以反复利用。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/30 11:55
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
def maxSubArrSum(arr):
  if arr == None or len(arr) <= 0:
    print('参数不合理!')
    return
  nAll = arr[0] # 最大子数组和
  nEnd = arr[0] # 包含最后一个元素的最大子数组和
  i = 1
  while i < len(arr):
    nEnd = max(nEnd + arr[i], arr[i])
    nAll = max(nEnd, nAll)
    i += 1
  return nAll


if __name__ == '__main__':
  arr = [1, -2, 4, 8, -4, 7, -1, -5]
  print('4 max sub array sum:', maxSubArrSum(arr))

结果:

python如何求数组连续最大和的示例代码

算法性能分析:
时间复杂度为O(n);
空间复杂度为O(1);

引申:

在知道了子数组的最大值后,如何确定最大子数组的和?

思路:

python如何求数组连续最大和的示例代码

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/30 12:01
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
class Test:
  def __init__(self):
    self.begin = 0 # 记录最大子数组起始位置
    self.end = 0 # 记录最大子数组结束位置

  def maxSubArrSum(self, arr):
    n = len(arr)
    maxSum = -2 ** 31 # 子数组最大值
    nSum = 0 # 包含子数组最后一位的最大值
    nStart = 0
    i = 0
    while i < n:
      if nSum < 0:
        nSum = arr[i]
        nStart = i
      else:
        nSum += arr[i]
      if nSum > maxSum:
        maxSum = nSum
        self.begin = nStart
        self.end = i
      i += 1
    return maxSum

  def getBegin(self):
    return self.begin

  def getEnd(self):
    return self.end


if __name__ == '__main__':
  arr = [1, -2, 4, 8, -4, 7, -1, -5]
  t = Test()
  print('连续最大和为:', t.maxSubArrSum(arr))
  print('begin at ', t.getBegin())
  print('end at ', t.getEnd())

结果:

python如何求数组连续最大和的示例代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 合并文件的具体实例
Aug 08 Python
使用python删除nginx缓存文件示例(python文件操作)
Mar 26 Python
python中列表元素连接方法join用法实例
Apr 07 Python
Python实现将不规范的英文名字首字母大写
Nov 15 Python
Python scikit-learn 做线性回归的示例代码
Nov 01 Python
浅谈python numpy中nonzero()的用法
Apr 02 Python
判断python字典中key是否存在的两种方法
Aug 10 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
Oct 29 Python
在pycharm下设置自己的个性模版方法
Jul 15 Python
Python os模块常用方法和属性总结
Feb 20 Python
通俗易懂了解Python装饰器原理
Sep 17 Python
class类在python中获取金融数据的实例方法
Dec 10 Python
tensorflow 实现自定义layer并添加到计算图中
Feb 04 #Python
TensorFlow实现自定义Op方式
Feb 04 #Python
tensorflow使用指定gpu的方法
Feb 04 #Python
TensorFlow梯度求解tf.gradients实例
Feb 04 #Python
基于TensorFlow中自定义梯度的2种方式
Feb 04 #Python
tensorflow 查看梯度方式
Feb 04 #Python
opencv python图像梯度实例详解
Feb 04 #Python
You might like
JAVA/JSP学习系列之四
2006/10/09 PHP
探讨PHP中this,self,parent的区别详解
2013/06/08 PHP
PHP基于自定义类随机生成姓名的方法示例
2017/08/05 PHP
PHP实现的文件浏览器功能简单示例
2019/09/12 PHP
使用PHP开发留言板功能
2019/11/19 PHP
一个用js实现的页内搜索代码
2007/05/23 Javascript
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
JS实现距离上次刷新已过多少秒示例
2014/05/23 Javascript
JavaScript获取当前url根目录(路径)
2016/06/17 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
2016/12/14 Javascript
jQuery插件FusionCharts绘制的2D双柱状图效果示例【附demo源码】
2017/05/13 jQuery
编写React组件项目实践分析
2018/03/04 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
angular5 子组件监听父组件传入值的变化方法
2018/09/30 Javascript
nodejs中用npm初始化来创建package.json的实例讲解
2018/10/10 NodeJs
vue cli安装使用less的教程详解
2019/07/12 Javascript
解决layui的input独占一行的问题
2019/09/10 Javascript
基于Layui自定义模块的使用方法详解
2019/09/14 Javascript
解决vue单页面应用打包后相对路径、绝对路径相关问题
2020/08/14 Javascript
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
Java实现的执行python脚本工具类示例【使用jython.jar】
2018/03/29 Python
Python 文本文件内容批量抽取实例
2018/12/10 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
用python实现英文字母和相应序数转换的方法
2019/09/18 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
2020/05/12 Python
Python如何绘制日历图和热力图
2020/08/07 Python
python实现暗通道去雾算法的示例
2020/09/27 Python
Python之字典对象的几种创建方法
2020/09/30 Python
python的scipy.stats模块中正态分布常用函数总结
2021/02/19 Python
css3 旋转按钮 使用CSS3创建一个旋转可变色按钮
2012/12/31 HTML / CSS
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
大学系主任推荐信范文
2013/12/24 职场文书
简历中个人自我评价范文
2013/12/26 职场文书
上课迟到检讨书
2014/01/19 职场文书
运动会加油稿
2015/07/22 职场文书
CSS巧用渐变实现高级感背景光动画
2021/12/06 HTML / CSS