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虚拟环境virtualenv的安装与使用详解
May 28 Python
python中is与双等于号“==”的区别示例详解
Nov 21 Python
Sanic框架配置操作分析
Jul 17 Python
在python 不同时区之间的差值与转换方法
Jan 14 Python
Python实现查找数组中任意第k大的数字算法示例
Jan 23 Python
python装饰器简介---这一篇也许就够了(推荐)
Apr 01 Python
用Python中的turtle模块画图两只小羊方法
Apr 09 Python
django 文件上传功能的相关实例代码(简单易懂)
Jan 22 Python
Python中私有属性的定义方式
Mar 05 Python
python中的selenium安装的步骤(浏览器自动化测试框架)
Mar 17 Python
详解Python3中的 input() 函数
Mar 18 Python
python快速安装OpenCV的步骤记录
Feb 22 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
php去除字符串换行符示例分享
2014/02/13 PHP
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
2014/12/22 PHP
基于JQuery的密码强度验证代码
2010/03/01 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
2014/08/12 Javascript
JS递归遍历对象获得Value值方法技巧
2016/06/14 Javascript
jquery实现网页定位导航
2016/08/23 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
JavaScript实现的选择排序算法实例分析
2017/04/14 Javascript
基于express中路由规则及获取请求参数的方法
2018/03/12 Javascript
js实现右键弹出自定义菜单
2020/09/08 Javascript
Python实现简单的获取图片爬虫功能示例
2017/07/12 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
Python 控制终端输出文字的实例
2019/07/12 Python
python 自定义装饰器实例详解
2019/07/20 Python
Python找出列表中出现次数最多的元素三种方式
2020/02/24 Python
python实现打砖块游戏
2020/02/25 Python
Python3 获取文件属性的方式(时间、大小等)
2020/03/12 Python
Python的信号库Blinker用法详解
2020/12/31 Python
德国珠宝和手表在线商店:VALMANO
2019/03/24 全球购物
美国庭院家具购物网站:AlphaMarts
2019/04/10 全球购物
全球最大化妆品零售网站:SkinStore
2020/10/24 全球购物
SQL语言面试题
2013/08/27 面试题
养殖行业的创业计划书
2014/01/05 职场文书
大学理论知识学习自我鉴定
2014/04/28 职场文书
2014离婚协议书范文两篇
2014/09/15 职场文书
纪念九一八事变83周年国旗下讲话稿
2014/09/15 职场文书
社区班子个人对照检查材料思想汇报
2014/10/07 职场文书
2014年政府采购工作总结
2014/12/09 职场文书
大学生旷课检讨书1000字
2015/02/19 职场文书
2015年政风行风工作总结
2015/04/21 职场文书
毕业晚宴祝酒词
2015/08/11 职场文书
七年级作文之雪景
2019/11/18 职场文书
python通过opencv调用摄像头操作实例分析
2021/06/07 Python
Python下opencv使用hough变换检测直线与圆
2021/06/18 Python