Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 找到2个连续的数组块,其和最大。还他们的钱_Algorithm_Max_Arrays - Fatal编程技术网

Algorithm 找到2个连续的数组块,其和最大。还他们的钱

Algorithm 找到2个连续的数组块,其和最大。还他们的钱,algorithm,max,arrays,Algorithm,Max,Arrays,块不能重叠。它们也不能相邻。假设A的长度大于2 我知道这与求最大子阵的和非常相似,并且可以在线性时间内完成 我也很确定,这个算法的开始与查找最大子数组问题的开始是一样的 这是我几天前听到的一个问题,我想看看如何解决它。2个步骤: 使用O(n)查找整个数组中最大和的块。假设该块从a[i]开始,以a[j]结束,其和为S1 使用O(n)查找前一个块的最小和的块。假设总和为S2 最后的答案是S1-S2 应考虑某些边界情况: 如果数组是1,2,3,2,1。步骤1将返回整个数组作为块。步骤2将返回1。但这违

块不能重叠。它们也不能相邻。假设A的长度大于2

我知道这与求最大子阵的和非常相似,并且可以在线性时间内完成

我也很确定,这个算法的开始与查找最大子数组问题的开始是一样的

这是我几天前听到的一个问题,我想看看如何解决它。

2个步骤:

  • 使用O(n)查找整个数组中最大和的块。假设该块从a[i]开始,以a[j]结束,其和为S1

  • 使用O(n)查找前一个块的最小和的块。假设总和为S2

  • 最后的答案是S1-S2

    应考虑某些边界情况:


    如果数组是1,2,3,2,1。步骤1将返回整个数组作为块。步骤2将返回1。但这违反了两个块不应相邻的要求。因此,对于第2步,你应该应用算法,从[i+1]开始,到[j-1]结束。你可以只做两次最大子数组算法

    算法
  • 我们定义了一个函数L[i],它表示a[i]之前的最大子数组的和。它可以从左到右用 O(n)复杂性
  • 我们定义了一个函数R[i],它表示a[i]之后的最大子数组的和。它可以做从右到左的最大子阵算法 O(n)复杂性
  • 从1扫描到n,答案将是最大的L[i]+R[i+1]。 这一步将是O(n)复杂度
  • 简单证明:任何解都可以从一个元素中分割出来 数组,所以我们可以只计算最大子数组前后的和 在每个地方之后
  • 代码
    def max_two_sub_array():
    总和=l[0]=ls[0]=0
    对于i=1到n:
    总和+=a[i]
    如果总和<0:sum=0
    如果l[i-1]>总和:
    l[i]=l[i-1]
    ls[i]=ls[i-1]#l[i]的端点
    其他的
    l[i]=总和
    ls[i]=i
    总和=r[n+1]=0
    rs[n+1]=n+1
    对于i=n到1:
    总和+=a[i]
    如果r[i+1]>和:
    r[i]=r[i+1]
    rs[i]=rs[i+1]#r[i]的起点
    其他的
    r[i]=总和
    rs[i]=i
    ans=0
    对于i=0到n:
    ans=最大值(ans,l[i]+r[i+1])
    返回ans
    
    想法不错,但如果A是[1,2,3,4,5,-100,5,4,3,2,1],该怎么办?所以正确的答案应该是[1,2,3,4,5],[5,4,3,2,1]。只有当你想要一个简单的和时,这个方法才有效。如果你想知道实际的细分市场,这是行不通的,是吗?有关提示,请参见@KonsolLabapen了解实际分段并非一项艰巨的任务。您可以添加另外两个函数LS[i](表示线段L[i]的端点)RS[i](表示线段R[i]的起点)@KonsolLabapen我已重新编辑解决方案。。。我认为它可以满足你的需求……如果你只需要一个数字,那么@Jun HU的答案就行了。否则,您需要使用
    子阵列求和
    来处理V序列对LIS和LDS的处理。结合和
    def max_two_sub_array():
        sum = l[0] = ls[0] = 0
        for i = 1 to n:
            sum += a[i]
            if sum < 0: sum = 0
            if l[i - 1] > sum:
                l[i] = l[i - 1]
                ls[i] = ls[i - 1] # endpoint of l[i]
            else
                l[i] = sum
                ls[i] = i
    
        sum = r[n + 1] = 0
        rs[n + 1] = n + 1
        for i = n to 1:
            sum += a[i]
            if r[i + 1] > sum:
                r[i] = r[i + 1]
                rs[i] = rs[i + 1] # startpoint of r[i]
            else
                r[i] = sum
                rs[i] = i
        ans = 0
        for i = 0 to n:
            ans = max(ans, l[i] + r[i + 1])
        return ans