算法题(4) 最大连续子数组和及子数组

最大连续子数组和及子数组

问题描述: 给定一个不为空的数组,数组中一个元素或多个连续元素和称为连续子数组和,找出给定数组中连续子数组和的最大值。

思路: 本题的思路有很多种,本文探讨三种最常用的解法,时间复杂度也各不相同。前两种通过暴力搜索的方式实现,时间复杂度为 O ( N 3 ) O(N^3) O(N3) O ( N 2 ) O(N^2) O(N2),效率较为低下;第三种方法采用的是“加入&抛弃”思想,仅需要遍历一次数组即可计算最大子数组和,时间复杂度为 O ( N ) O(N) O(N)。下面我们逐一讲解。

一、三重循环暴力搜索
  三重循环的暴力搜索是本题最基本的搜索方法,我们首先需要设置起始下标、结束下标来定位数组中的子数组,添加另一个for循环来遍历子数组以求和,其时间复杂度为 O ( N 3 ) O(N^3) O(N3),空间复杂度为 O ( 1 ) O(1) O(1)。代码如下:

  def tribfsearch(self, array):
        array = array
        if len(array) == 0: return
        maxsum = array[0]
        sum = 0
        maxarray = [array[0]]
        for i in range(len(array)):
            for j in range(i, len(array)):
                for k in range(i, j+1):
                    sum += array[k]
                if sum > maxsum :
                    maxsum = sum
                    maxarray = array[i:j+1]
                sum = 0
        print(maxsum, 'Max Subarray:', maxarray)
        return

二、二重循环暴力搜索
  二重循环的暴力搜索较于三重循环效率有一定的提升,不同之处在于二重循环是在遍历起始、结束下标的同时进行求和计算,因此不需要再添加for循环来求和。代码如下:

   def bibfsearch(self, array):
        array = array
        if len(array) == 0: return
        maxarray = [array[0]]
        maxsum = array[0]
        sum = 0
        for i in range(len(array)):
            for j in range(i, len(array)):
                sum += array[j]
                if sum > maxsum :
                    maxsum = sum
                    maxarray = array[i:j+1]
            sum = 0
        print(maxsum,'Max Subarray:', maxarray)
        return

三、“加入&抛弃”方法
  使用“加入&抛弃”方法则只用一次循环即可完成最大子数组和的计算。该方法的思路是:设置一个局部子数组和的变量,首先设数组的第一个元素为局部和,在迭代的过程中,将当前元素同局部和求和,如果结果小于或等于0,则将当前局部和的结果抛弃,从下一个元素开始计算和;大于0则继续累加。找出局部和的最大值即可。公式和代码实现如下:
在这里插入图片描述

 def compact(self, array):
        array = array
        if len(array) == 0: return
        maxsum = array[0]
        begin = 0
        end = begin + 1
        left = 0
        sum = array[0]
        for i in range(1, len(array)):
            if sum <= 0:
                sum = array[i]
                left = i
                right = i + 1
            else:
                sum += array[i]
                right = i+1
            if maxsum < sum :
                maxsum = sum
                begin = left
                end = right
        maxarray = array[begin:end]
        print(maxsum,'Max Subarray:', maxarray)
        return

  上述代码的最终输出结果均如下所示,所有方法均输出最大子序列和以及子序列:
在这里插入图片描述
  该方法归类为动态规划方法,但个人认为该方法的动态规划思想并不明显,因为动态规划是先求出子问题,然后求解原问题时参考子问题的结果来做出决策。而该方法虽然考虑了子问题,但子问题是dp[i-1],判断准则是其是否大于0. 因此个人认为该方法类似于“加入、抛弃”操作,不断加入新元素,并根据局部和是否为正数判断其能否构成最大子序列的一部分,能则继续添加新元素,不能则重新计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值