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 ~

相关推荐
幸运超级加倍~13 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan2019031320 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法22 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR22 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer23 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_0125 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_4340859026 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will27 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev29 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
蒙娜丽宁30 分钟前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉