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中的type()方法的使用
May 21 Python
解决Tensorflow使用pip安装后没有model目录的问题
Jun 13 Python
python 画三维图像 曲面图和散点图的示例
Dec 29 Python
python使用Paramiko模块实现远程文件拷贝
Apr 30 Python
django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
Jun 27 Python
Python实现蒙特卡洛算法小实验过程详解
Jul 12 Python
django mysql数据库及图片上传接口详解
Jul 18 Python
tensorflow之tf.record实现存浮点数数组
Feb 17 Python
浅谈SciPy中的optimize.minimize实现受限优化问题
Feb 29 Python
matlab 计算灰度图像的一阶矩,二阶矩,三阶矩实例
Apr 22 Python
详解python tcp编程
Aug 24 Python
python+opencv实现车道线检测
Feb 19 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和ACCESS写聊天室(一)
2006/10/09 PHP
使用时间戳解决ie缓存的问题
2014/08/20 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
浅析Ajax语法
2016/12/05 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
js获取地址栏参数的两种方法
2017/06/27 Javascript
基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式
2018/01/17 Javascript
JS将网址url转化为JSON格式的方法
2018/07/02 Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
2018/09/03 Javascript
webpack的pitching loader详解
2019/09/23 Javascript
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
python中列表元素连接方法join用法实例
2015/04/07 Python
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
利用python实现简单的邮件发送客户端示例
2017/12/23 Python
python创建列表和向列表添加元素的实现方法
2017/12/25 Python
Flask和Django框架中自定义模型类的表名、父类相关问题分析
2018/07/19 Python
Python 移动光标位置的方法
2019/01/20 Python
使用Python将Mysql的查询数据导出到文件的方法
2019/02/25 Python
Python安装Flask环境及简单应用示例
2019/05/03 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
python 获取计算机的网卡信息
2021/02/18 Python
CSS3 三维变形实现立体方块特效源码
2016/12/15 HTML / CSS
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
《望洞庭》教学反思
2014/02/16 职场文书
水毁工程实施方案
2014/04/01 职场文书
初三学生个人自我评定
2014/04/06 职场文书
保卫钓鱼岛口号
2014/06/20 职场文书
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
幼儿园见习报告范文
2014/10/30 职场文书
试用期辞职信范文
2015/03/02 职场文书
环境卫生标语
2015/08/03 职场文书
Oracle11g R2 安装教程完整版
2021/06/04 Oracle
redis中lua脚本使用教程
2021/11/01 Redis
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python
Spring Boot 实现 WebSocket
2022/04/30 Java/Android
SQL中的连接查询详解
2022/06/21 SQL Server