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 ~

相关推荐
万法若空4 分钟前
排列组合恒等式
c++·算法
Data_Journal6 分钟前
如何使用 Python 抓取 Google Flights:分步指南
大数据·开发语言·数据库·python·scrapy
Nil20821 分钟前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
你我一见如故23 分钟前
仿QQ音乐桌面客户端——测试报告
python·selenium
一直C26 分钟前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
淡海水28 分钟前
04-02-哈希-Dictionary-TKey-TValue-上-核心数据结构
数据结构·算法·c#·哈希算法·编译·字典·dictionary
Kismet_nvi33 分钟前
Python 基础核心知识点总结
开发语言·windows·python
戴西软件34 分钟前
国内有哪些数据轻量化格式转换软件?
数据库·算法·安全·信息可视化·自动化·rpa
2401_8445829537 分钟前
冷门技巧:AI模型可靠性测试的实用技巧:数
python
you鬰43 分钟前
datawhale--llm-algo-leetcode5️⃣
python·datawhale