• 最大子数组和问题


    (一)最大字数组和问题

      问题:给定n个整数(可能为负数)组成的序列a[1],a[2]…a[n],求该序列a[i],a[i+1]…a[j]的子段和的最大值。当所给整数均为负数的时候,定义子段和为0.《百度百科

    • 分析

      显然问题可以在O(n2)的时间复杂度上解决,但是考虑到当n很大(比如1e9)时,O(n2)的时间复杂度并不能完美的解决这个问题。因此我们是否可以对O(n2)的代码进行优化呢?答案是肯定的。
      不妨设,a[i],a[i+1]...a[j]已经是所求最大子数组和的部分前缀并且已知和为sum且当前最大子数组和为maxx,继续考虑a[j+1]的情况,如果sum加上a[j+1]可以使和sum大于a[j+1],则更新sum的值为sum + a[i]反之更新sum的值为a[i]。由此我们可以得到递推公式

    sum = max(sum + a[i], a[i])

      当sum的值大于已知最大字数组和maxx的时候更新maxx即可。

    • Python代码
    import math
    
    def fun(arr):
        n = len(arr)
        if n <= 0:
            return 0
        sum = 0
        maxx = 0
        
        for i in range(0, n):
            sum = max(sum + arr[i], arr[i])
            if sum >= maxx:
                maxx = sum
                
        return maxx
    

      代码地址

    • 流程图

    算法流程图

    • 单元测试

      接下来我们使用单元测试来测试一下代码,一下是单元测试代码:

    import my_math, unittest
    
    arr0 = []
    arr1 = [-1, -2, -3, -4]
    arr2 = [-2, 11, -4, 13, -2, -5]
    
    class ProductTestCase(unittest.TestCase):
        def test0(self):
            p = my_math.fun(arr0)
            self.assertEqual(0, p, 'Worng Answer!')
        
        def test1(self):
            p = my_math.fun(arr1)
            self.assertEqual(0, p, 'Worng Answer!')
        
        def test2(self):
            p = my_math.fun(arr2)
            self.assertEqual(20, p, 'Worng Answer!')
            
    if __name__=='__main__': unittest.main()
    

      本测试代码实现了条件覆盖,样例数组arr0为空测试数组长度小于等于0的情况(实际小于0的情况不存在),arr1数组测试数组值全为负数时返回最大子数组和为0,arr2数组可以测试sum>=maxx的两个条件。测试代码结果如下:
    测试结果

  • 相关阅读:
    程序员需要的各种PDF格式电子书【附网盘免费下载资源地址】
    Web安全大揭秘
    tar 压缩解压命令详解
    django开发项目的部署nginx
    CentOS7安装mysql-python模块
    我的博客站点上线了
    2006
    centos7安装pip
    mysql删除匿名用户
    FilenameFilter 文件名过滤
  • 原文地址:https://www.cnblogs.com/ulyssesgao/p/10707218.html
Copyright © 2020-2023  润新知