Algorithm 阵列中所有可能子阵列的最大值

Algorithm 阵列中所有可能子阵列的最大值,algorithm,array-algorithms,Algorithm,Array Algorithms,如何查找/存储长度为n的数组中所有可能的非空子数组的最大值/最小值 我为每个可能的子数组生成了数组的段树,如果查询到段树,则为每个可能的子数组生成段树,但这并不高效。我如何在O(n)中完成它 p.sn我认为不可能直接在O(n)时间内完成:你需要迭代子数组的所有元素,你有n个元素。除非子阵列已排序 另一方面,您可以在初始化子阵列时,而不是使其成为普通阵列,您可以构建堆,特别是当您要查找最小值时的最小堆和当您要查找最大值时的最大堆 ,并且分别检索最大堆和最小堆的最大值和最小值是一个固定时间操作,因为

如何查找/存储长度为n的数组中所有可能的非空子数组的最大值/最小值

我为每个可能的子数组生成了数组的段树,如果查询到段树,则为每个可能的子数组生成段树,但这并不高效。我如何在O(n)中完成它


p.sn我认为不可能直接在O(n)时间内完成:你需要迭代子数组的所有元素,你有n个元素。除非子阵列已排序

另一方面,您可以在初始化子阵列时,而不是使其成为普通阵列,您可以构建堆,特别是当您要查找最小值时的最小堆和当您要查找最大值时的最大堆

,并且分别检索最大堆和最小堆的最大值和最小值是一个固定时间操作,因为这些元素位于堆的第一个位置

仅使用普通数组就可以轻松实现堆


查看维基百科上关于二进制堆的这篇文章:。

我不明白您所说的最大子数组数到底是什么意思,因此我假设您要求的是以下内容之一

  • 最大/最小长度的子数组或其他一些标准(在这种情况下,问题将归结为在一维数组中查找最大元素)
  • 在一个子数组的上下文或整个超级数组的上下文中,所有子数组的最大元素数

  • 问题1可以通过简单地迭代超级数组并存储对最大元素的引用来解决。或者像nbro说的那样堆起来。问题2也有类似的解决方案。但是,线性扫描是通过长度为
    n
    的数组进行的
    m
    不是线性的。因此,您必须保持类不变量,以便在每次操作后都知道最大值/最小值。可能借助于堆之类的数据结构。

    假设您指的是连续子数组,创建部分和数组,其中Yi=SUM(i=0..i)Xi,因此从1,4,2,3创建0,1,1+4=5,1+4+2=7,1+4+2+3=10。您可以在线性时间内从左到右创建它,任何连续子数组的值都是一个部分和减去另一个部分和,因此4+2+3=1+4+2+3-1=9

    然后从左到右扫描部分和,跟踪到目前为止看到的最小值(包括初始零)。在每个点从当前值中减去该值,并跟踪以这种方式产生的最高值。这将为您提供具有最大和的连续子数组的值,并且您还可以保留索引信息,以查找该子数组的开始和结束位置


    要找到最小值,可以稍微改变上面的数字,或者只是颠倒所有数字的符号,然后再做完全相同的事情:min(a,b)=-max(-a,-b)

    我认为不可能将所有这些值存储在O(n)中。但在O(n)中,很容易创建一个结构,在O(1)中回答“a[i]为最大元素的有多少子集”的查询

    天真的版本: 想想天真的策略:为了知道某个A[i]有多少这样的子集,可以使用一个简单的O(n)算法来计算数组左侧和右侧有多少元素小于A[i]。比如说:

    A = [... 10 1 1 1 5 1 1 10 ...]
    
    5
    up的左侧有3个元素,右侧有2个元素小于它。从这里我们知道有
    4*3=12
    子阵列,其中
    5
    是最大值
    4*3
    因为左侧有
    0..3
    子阵列,右侧有
    0..2

    优化版本: 这个天真版本的检查会对每个元素进行O(n)操作,所以O(n^2)毕竟是这样。如果我们能在一次过程中以O(n)来计算所有这些长度,那不是很好吗

    幸运的是,有一个简单的算法。只需使用堆栈。正常遍历阵列(从左到右)。将每个元素索引放入堆栈中。但在放入之前,请删除所有值小于当前值的索引。当前索引之前的剩余索引是最近的较大元素

    要在右侧找到相同的值,只需向后遍历数组

    下面是一个示例Python概念验证,展示了该算法的实际应用。我还实现了naïve版本,因此我们可以交叉检查优化版本的结果:

    来自随机导入选择
    从集合导入defaultdict,deque
    def生成界限(A、回退、arange、op):
    stack=deque()
    绑定=[fallback]*len(A)
    对于我在阿兰格:
    而stack和op(A[stack[-1]],A[i]):
    stack.pop()
    如果堆栈:
    绑定[i]=堆栈[-1]
    stack.append(i)
    回程
    def优化版(A):
    T=zip(make_界限(A,-1,xrange(len(A)),λx,y:x=A[i]),len(A))
    答案[x]+=(左一)*(右一)
    返回指令(答案)
    A=[选择(xrange(32))用于xrange(8)中的i]
    MA1=原始版本(A)
    MA2=优化的_版本(A)
    打印“数组:”,A
    打印“朴素:”,MA1
    打印“优化:”,MA2
    打印“确定:”,MA1==MA2
    
    我认为您要问的问题是找到子数组的最大值。 bleow是在O(n)时间内可以完成的代码

    int-maxsumr(向量a)
    {
    int maxsum=*max_元素(a.begin(),a.end());
    如果(maxsum<0)返回maxsum;
    整数和=0;
    for(int i=0;i最大总和)最大总和=总和;
    如果(总和<0)总和=0;
    }
    返回最大和;
    }
    

    注:此代码未被测试,如果发现问题,请添加注释。< /P>数组是否排序?请提供示例数据(即使小于实际)和预期结果。您在寻找算法还是C++代码?如果您正在寻找一种算法,那么语言应该无关紧要,也许应该删除
    C++
    标记
    A = [... 10 1 1 1 5 1 1 10 ...]
    
    int maxSumSubArr(vector<int> a)
    {
        int maxsum = *max_element(a.begin(), a.end());
        if(maxsum < 0) return maxsum;
        int sum = 0;
        for(int i = 0; i< a.size; i++)
        {
          sum += a[i];
          if(sum > maxsum)maxsum = sum;
          if(sum < 0) sum = 0;
        }
        return maxsum;
    }