算法要求:
给定输入arr和sumindex, 根据sum_index中元素生成新数组,规则如下:
遍历数组sumindex, arr数组的坐标从leftlighting到right_lighting(包含两个边界)的元素加value的和作为该坐标的新值。
Input:
arr -- list of int, for example [0,0,0,0,0,0,0,0]
sum_index -- list of (left_lighting, right_lighting, value), for example [(0,3,2),(6,7,4),(0,2,3)]
Output:
result -- list of int, for example [5,5,5,2,0,0,4,4]
普通算法:
优点:逻辑最贴近普通人的思维,简洁明了,不绕弯。
缺点:算法复杂度O(n2), 比较重
>>>arr=[0]*8
>>>arr
[0,0,0,0,0,0,0,0]
>>>for item in sum_index:
... for i in range(item[0],item[1]+1):
... arr[i]+=item[2]
...
>>>arr
[5,5,5,2,0,0,4,4]
进阶算法:
思路:1)只记录当前元素和上一个元素的变化趋势,第一个元素是+5,第二个元素跟第一个元素没有变化就是+0,第三个跟第二个元素没有变化也是+0,第四个元素跟第三个元素小3就是-3,第五个跟第四个比小2就是-2,第六个跟第五个比没有变化就是+0,第七个跟第六个比就是+4,第八个跟第七个没有变化就是+0;2)然后根据变化趋势的list[+5,0,0,-3,-2,0,+4,0]生成新的数组。1)和2)的复杂度都是O(n),两步相加复杂度还是O(n)
优点:算法复杂度低,只有O(n)
缺点:比较烧脑,容易掉头发
>>> len=8
>>> arr=[0]*len
>>> arr
[0, 0, 0, 0, 0, 0, 0, 0]
>>> sum_index=[(0,3,2),(6,7,4),(0,2,3)]
>>>
>>> op_list=[0]*len
>>> op_list
[0, 0, 0, 0, 0, 0, 0, 0]
>>> for item in sum_index:
... op_list[item[0]] += item[2]
... if item[1] + 1 < len:
... op_list[item[1]+1] -= item[2]
...
>>> op_list
[5, 0, 0, -3, -2, 0, 4, 0]
>>>
>>>
>>> for index,value in enumerate(op_list):
... arr[index] = arr[index] + op_list[index] if index == 0 else arr[index-1] + op_list[index]
...
>>> arr
[5, 5, 5, 2, 0, 0, 4, 4]