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

 更新时间:2020年02月04日 11:33:01   作者:布欧不欧  
这篇文章主要介绍了python如何求数组连续最大和的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

题目描述:

一个有 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))

结果:


算法性能分析:
这种方法的时间复杂度为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))

结果:


算法性能分析:
使用了双重循环,时间复杂度为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] 的最大子数组。
所以有:


代码实现:

#!/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))

结果:


算法性能分析:
时间复杂度为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))

结果:


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

引申:

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

思路:


代码实现:

#!/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生成图文并茂的PDF报告的方法详解

    Python生成图文并茂的PDF报告的方法详解

    reportlab是Python的一个标准库,可以画图、画表格、编辑文字,最后可以输出PDF格式。本文将利用reportlab模块生成图文并茂的PDF报告,感兴趣的可以了解一下
    2022-06-06
  • Python 正则表达式的非捕获组详解

    Python 正则表达式的非捕获组详解

    非捕获组 ((?:...)) 在 Python 正则表达式中用于分组但不保存匹配结果,通过 '?' 表示非捕获标记,常用于简化正则表达式和提高性能,它在选择、提高匹配性能和结构化复杂表达式方面都有优势,本文介绍Python 正则表达式的非捕获组的相关知识,感兴趣的朋友一起看看吧
    2025-02-02
  • python实现五子棋游戏(pygame版)

    python实现五子棋游戏(pygame版)

    这篇文章主要为大家详细介绍了python实现五子棋游戏,pygame版五子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • python中的deque基本用法详解

    python中的deque基本用法详解

    Python 中的 deque是一个低级别的、高度优化的双端队列,对于实现优雅、高效的Pythonic队列和堆栈很有用,这篇文章主要介绍了python中的deque基本用法的相关资料,需要的朋友可以参考下
    2017-11-11
  • python  dataclass 快速创建数据类的方法

    python  dataclass 快速创建数据类的方法

    在Python中,dataclass是一种用于快速创建数据类的装饰器和工具,本文实例代码中我们定义了一个Person数据类,并使用fields()函数遍历其字段,打印出每个字段的名称、类型、默认值和元数据,对python  dataclass 数据类相关知识感兴趣的朋友一起看看吧
    2024-03-03
  • python 正则表达式的使用

    python 正则表达式的使用

    这篇文章主要介绍了python 正则表达式的使用,Python 中正则表达式应用非常广泛,如数据挖掘、数据分析、网络爬虫、输入有效性验证等,Python 也提供了利用正则表达式实现文本的匹配、查找和替换等操作的 re 模块,下面和小编一起进入文章了解具体内容吧
    2021-10-10
  • Python用selenium实现自动登录和下单的项目实战

    Python用selenium实现自动登录和下单的项目实战

    本文主要介绍了Python用selenium实现自动登录和下单的项目实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • python csv一些基本操作总结

    python csv一些基本操作总结

    今天给大家带来的是关于Python的相关知识,文章围绕着python csv的一些基本操作展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Python3爬虫里关于Splash负载均衡配置详解

    Python3爬虫里关于Splash负载均衡配置详解

    在本篇文章里小编给大家分享了关于Python3爬虫里关于Splash负载均衡配置的相关内容,需要的朋友们可以学习参考下。
    2020-07-07
  • Python接口自动化之cookie、session应用详解

    Python接口自动化之cookie、session应用详解

    本文主要介绍cookie、session原理及在自动化过程中如何利用cookie、session保持会话状态的应用,有需要的朋友可以参考下,希望可以有所帮助
    2021-08-08

最新评论