【问题标题】:Increment value of every element in an array in a particular range在特定范围内增加数组中每个元素的值
【发布时间】:2019-12-18 08:59:06
【问题描述】:

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

我已经尝试过使用嵌套循环方法的 O(n^2) 解决方案。如果存在,我真的无法弄清楚 O(n) 解决方案。

i=1;
while(i<=n)
{
start=(i-A[i]<1)?1:i-A[i];
end=(i+A[i]>n)?n:i+A[i];
while(start<=end)
{
B[start]+=1;
start+=1;
}
i+=1;
}

【问题讨论】:

  • 您不应该每次都增加范围本身,而是跟踪要迭代的数量,然后再做。
  • @WillemVanOnsem 您能否详细说明您的建议?

标签: arrays loops logic time-complexity increment


【解决方案1】:

一个简单的实现是增加 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 的会被忽略)。

在图像中,第一行显示索引,接下来我们表示来自同一输入的范围,接下来我们显示将放在无限磁带上的增量和减量,接下来我们显示累积和。

算法在O(n)中工作:首先我们以线性时间迭代la,并增加和减少b中的相应元素。接下来我们迭代b,再次在O(n)中计算累积和。

【讨论】:

  • 如果我考虑数组 A=[1,2,3,4,5],根据我指定的条件,数组 B 应该是 B=[3,4,4,5,5]题。您建议的代码显示 B=[4,4,5,5,5] 的输出。 :(
  • @YashSarwaswa:为什么数组应该是[3,4,4,5,5]?这里所有范围都从0 开始,所以范围是(0,2), (0, 4), (0, 6)...
  • @YashSarwaswa:因此建议的输出是[5, 5, 4, 4, 3],因为在索引0,它是5,在索引1又是5,等等。
猜你喜欢
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 2022-07-06
相关资源
最近更新 更多