有一个包含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
答案 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
进行迭代,以计算累积和。