Python算法题集_最大子数组和

本文为Python算法题集之一的代码示例

题目53:最大子数组和

说明:给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105

  • -104 <= nums[i] <= 104


- 问题分析

  1. 本题为求数组中的子数组的最大和
  2. 主要的计算为2个,1子数组遍历,2子数组求和
  3. 基本的遍历为双层循环,双层循环遍历子数组,每个子数组求和一次,所以基本的时间算法复杂度为(On2)

- 优化思路

  1. 减少循环层次

  2. 减少计算类别

  3. 通过动态规划分析最优路径

    1. 前缀和之差(第1到第n的累加为前缀和,前缀和之间的差为两个元素之间子数组的和)
    2. 递归思路,第n个元素为止的最大和,为之前的最大和max_n与包含元素n的子数组最大和【max(premax+元素n、元素n)】中最大者


  1. 标准求解,双层循环,超时失败

    python 复制代码
    import CheckFuncPerf as cfp
    
    def maxSubArray_base(nums):
        if len(nums) == 1:
            return nums[0]
        imaxsum, ileftsum = nums[0], nums[0]
        for iIdx in range(len(nums)-1):
            ileftsum += nums[iIdx]
            irightsum = 0
            for jIdx in range(iIdx+1, len(nums)):
                irightsum += nums[jIdx]
                if ileftsum > 0:
                    if ileftsum+irightsum > imaxsum:
                        imaxsum = ileftsum+irightsum
                else:
                    if irightsum > imaxsum:
                        imaxsum = irightsum
        return imaxsum
    
    testcase_big = open(r'testcase/hot13_big.txt', mode='r', encoding='utf-8').read().replace('[', '').replace(']', '')
    testcase_big = testcase_big.split(',')
    nums = [int(x) for x in testcase_big]
    result = cfp.getTimeMemoryStr(maxSubArray_base, nums)
    print(result['msg'], '执行结果 = {}'.format(result['result']))
    
    # 运行结果
    函数 maxSubArray_base 的运行时间为 19834.08 ms;内存使用量为 4.00 KB 执行结果 = 1364833
  2. 优化版一【采用前缀和】,虽有想法,超时依旧

    python 复制代码
    import CheckFuncPerf as cfp
    
    def maxSubArray_ext1(nums):
        if len(nums) == 1:
            return nums[0]
        presum = [0] * len(nums)
        isum, imaxsum = 0, nums[0]
        for iIdx in range(len(nums)):
            isum += nums[iIdx]
            presum[iIdx] = isum
        for iIdx in range(len(nums)-1):
            for jIdx in range(iIdx+1, len(nums)):
                imaxsum = max(imaxsum, presum[iIdx], presum[jIdx], presum[jIdx]-presum[iIdx])
        return imaxsum
    
    testcase_big = open(r'testcase/hot13_big.txt', mode='r', encoding='utf-8').read().replace('[', '').replace(']', '')
    testcase_big = testcase_big.split(',')
    nums = [int(x) for x in testcase_big]
    result = cfp.getTimeMemoryStr(maxSubArray_ext1, nums)
    print(result['msg'], '执行结果 = {}'.format(result['result']))
    
    # 运行结果
    函数 maxSubArray_ext1 的运行时间为 15518.62 ms;内存使用量为 144.00 KB 执行结果 = 1364833
  3. 优化版二【滑动窗口,单层循环】,勉强通过,超过27%

    python 复制代码
    import CheckFuncPerf as cfp
    
    def maxSubArray_ext2(nums):
        if len(nums) == 1:
            return nums[0]
        presum = [0] * len(nums)
        isum, imaxsum, iminsum = 0, nums[0], nums[0]
        for iIdx in range(len(nums)):
            isum += nums[iIdx]
            presum[iIdx] = isum
            if iIdx > 0:
                imaxsum = max(imaxsum, isum, isum - iminsum)
            iminsum = min(isum, iminsum)
        return imaxsum
    
    testcase_big = open(r'testcase/hot13_big.txt', mode='r', encoding='utf-8').read().replace('[', '').replace(']', '')
    testcase_big = testcase_big.split(',')
    nums = [int(x) for x in testcase_big]
    result = cfp.getTimeMemoryStr(maxSubArray_ext2, nums)
    print(result['msg'], '执行结果 = {}'.format(result['result']))
    
    # 运行结果
    函数 maxSubArray_ext2 的运行时间为 6.99 ms;内存使用量为 296.00 KB 执行结果 = 1364833
  4. 优化版三【动态规划,递归思路求解】,马马虎虎,超过60%

    python 复制代码
    import CheckFuncPerf as cfp
    
    def maxSubArray_ext3(nums):
        imaxpre, imaxsum = 0, nums[0]
        for iIdx in range(len(nums)):
            imaxpre = max(nums[iIdx], nums[iIdx] + imaxpre)
            imaxsum = max(imaxsum, imaxpre)
        return imaxsum
    
    testcase_big = open(r'testcase/hot13_big.txt', mode='r', encoding='utf-8').read().replace('[', '').replace(']', '')
    testcase_big = testcase_big.split(',')
    nums = [int(x) for x in testcase_big]
    result = cfp.getTimeMemoryStr(maxSubArray_ext3, nums)
    print(result['msg'], '执行结果 = {}'.format(result['result']))
    
    # 运行结果
    函数 maxSubArray_ext3 的运行时间为 5.99 ms;内存使用量为 4.00 KB 执行结果 = 1364833
  5. 优化版四【分支改良】,有所改善,超越83%

    在优化版四的基础上,进行流程分支改良,去掉了一批加法计算

    python 复制代码
    import CheckFuncPerf as cfp
    
    def maxSubArray_ext4(nums):
        imaxpre, imaxsum = 0, nums[0]
        for iIdx in range(len(nums)):
            if imaxpre > 0:
                imaxpre = nums[iIdx] + imaxpre
            else:
                imaxpre = nums[iIdx]
            imaxsum = max(imaxsum, imaxpre)
        return imaxsum
    
    testcase_big = open(r'testcase/hot13_big.txt', mode='r', encoding='utf-8').read().replace('[', '').replace(']', '')
    testcase_big = testcase_big.split(',')
    nums = [int(x) for x in testcase_big]
    result = cfp.getTimeMemoryStr(maxSubArray_ext4, nums)
    print(result['msg'], '执行结果 = {}'.format(result['result']))
    
    # 运行结果
    函数 maxSubArray_ext4 的运行时间为 4.02 ms;内存使用量为 0.00 KB 执行结果 = 1364833

    一日练,一日功,一日不练十日空

    may the odds be ever in your favor ~

相关推荐
qq_529025298 分钟前
Torch.gather
python·深度学习·机器学习
数据小爬虫@8 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
XiaoLeisj21 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Cachel wood40 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Jasmine_llq41 分钟前
《 火星人 》
算法·青少年编程·c#
終不似少年遊*1 小时前
pyecharts
python·信息可视化·数据分析·学习笔记·pyecharts·使用技巧
Python之栈1 小时前
【无标题】
数据库·python·mysql
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
袁袁袁袁满1 小时前
100天精通Python(爬虫篇)——第113天:‌爬虫基础模块之urllib详细教程大全
开发语言·爬虫·python·网络爬虫·爬虫实战·urllib·urllib模块教程