数组中每个元素在特定范围内的增量值

时间:2019-08-11 12:43:41

标签: arrays loops logic time-complexity increment

有一个包含n个元素的数组A []。还有另一个大小为n的数组B [],每个元素都初始化为零。对于范围从1到n的每个i,需要将范围i-A_i到i + A_i(包括i)的B []元素增加1。

我已经使用嵌套循环方法尝试了O(n ^ 2)解决方案。我真的无法找出O(n)解决方案是否存在。

12750f964708        jaspeen/oracle-11g   "/assets/entrypoint.…"   17 seconds ago      Exited (1) 16 seconds ago                       busy_dewdney

1 个答案:

答案 0 :(得分:0)

一个简单的实现是增加 A 中每个项目的每个范围,但是您不需要这样做。您可以先通过在增量应开始的1和增量应停止的-1处“准备”数组。接下来,您可以计算数组的累积和。喜欢:

def fill_list(la):
    lb = [0]*len(la)
    n1 = len(la)-1
    for i, a in enumerate(la, 1):
        xf, xt = i-a, i+a+1
        lb[max(0, i-a)] += 1
        if xt <= n1:
            lb[xt] -= 1
    c = 0
    for i, b in enumerate(lb):
        c += b
        lb[i] = c
    return lb

或者如果您想返回1到n的范围:

def fill_list1(la):
    n1 = len(la)
    lb = [0]*(n1+1)
    for i, a in enumerate(la, 1):
        xf, xt = i-a, i+a+1
        lb[max(0, i-a)] += 1
        if xt <= n1:
            lb[xt] -= 1
    c = 0
    for i, b in enumerate(lb):
        c += b
        lb[i] = c
    return lb[1:]

然后我们可以使用以下方法生成列表:

>>> fill_list([1,4,2,5,1,3,0,2])
[4, 4, 4, 5, 5, 5, 4, 3]
>>> fill_list1([1,2,3,4,5])
[5, 5, 4, 4, 3]

因此,其范围为:

 -3 -2 -1  0  1  2  3  4  5  6  7  8  9 10 11
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
           |-----|
     |-----------------------|
              |-----------|
        |-----------------------------|
                       |-----|
                    |-----------------|
                                |
                             |-----------|
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
  0  1  1  1  1  0  0  1  0  0 -1 -1 -1 -2 -1
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
  0  1  2  3  4  4  4  5  5  5  4  3  3  1  0

在范围开始之前完成的增量(因此索引小于0)仅放在索引0处,以便我们将其考虑在内。在窗口之后执行的操作(因此索引大于或等于 n 的值将被忽略)。

在图像中,第一行显示了索引,接下来,我们指示了来自相同输入的范围,接下来,我们显示了将要在无限大的磁带上放置的增量和减量,然后显示了累积和。 / p>

该算法在 O(n)中工作:首先,我们在线性时间内对la进行迭代,然后递增和递减b中的相应元素。接下来,我们再次在{em> O(n)中对b进行迭代,以计算累积和。