用于理解数组行为的算法

时间:2017-06-24 16:46:44

标签: python algorithm performance

您将获得一个大小为N的列表,用零初始化。您必须在列表上执行M操作并输出列表中所有N个元素的最大值。对于每个操作,您将获得三个整数a,b和k,并且您必须为从索引到(包括两者)的所有元素添加值。

输入格式

第一行将包含由单个空格分隔的两个整数N和M. 接下来的M行将包含由单个空格分隔的三个整数a,b和k。 列表中的数字从1到N编号。

约束
Click here

输出格式

在更新列表中包含最大值的单行。

示例输入

  

5 3
  1 2 100
  2 5 100
  3 4 100

示例输出

  

200

解释
第一次更新后的列表将是100 100 0 0 0 第二次更新后的清单将是100 200 100 100 100. 第三次更新后的清单将是100 200 200 200 100. 所以答案必须是200.

时间复杂度较低的解决方案之一

n, inputs = [int(n) for n in input().split(" ")]
list = [0]*(n+1)
for _ in range(inputs):
    x, y, incr = [int(n) for n in input().split(" ")]
    list[x-1] += incr
    if((y)<=len(list)): 
        list[y] -= incr
max = x = 0
for i in list:
    x=x+i;
    if(max<x):max=x
print(max)

有人可以解释上述解决方案吗?

1 个答案:

答案 0 :(得分:1)

基本上它存储增量而不是最终列表;这意味着每个操作只需要2次读写而不是(b - a + 1)。然后,最后的max扫描会随着时间的推移添加增量,这仍然是O(n)操作,无论如何你都必须这样做。

n, inputs = [int(n) for n in input().split(" ")]

获取列表大小(n)和操作数(m),即53

list = [0]*(n+1)

创建一个空的0填充列表。应该是lst = [0] * n(不要使用list作为变量名,它会影响内置类型)(我们不需要额外的结束单元格,除非作为我们算法的校验和 - 如果它有效正确的最终校验和应为0)。

for _ in range(inputs):
    x, y, incr = [int(n) for n in input().split(" ")]

获取操作(a,b,k),即12100

    list[x-1] += incr

将delta添加到起始单元格

    if((y)<=len(list)): 
        list[y] -= incr

从结束单元格中减去增量(应为if y < n: lst[y] -= incr

如果您在此处添加print(lst)if之后但在for循环内),则该算法可能更容易理解。

现在处理增量以找到最大项目:

max = x = 0
for i in list:
    x=x+i;

x现在是当前列表单元格的实际值。此外,max是一个可怕的变量名称,因为它会影响内置的max()函数。

    if(max<x):max=x

保持最大运行

print(max)

显示结果。