在Codility上测试Python得分为100/100,时间复杂度为O(nlogn),空间复杂度为O(n)。
这里是@noisyboiler对@Aryabhatta方法的Python实现,包含注释和示例。完全归功于原始作者,任何错误/措辞不当都是我的错。
from bisect import bisect_right
def number_of_disc_intersections(A):
pairs = 0
intervals = sorted( [(i-A[i], i+A[i]) for i in range(len(A))] )
starts = [i[0] for i in intervals]
for i in range(len(starts)):
disk_end = intervals[i][1]
count = bisect_right(starts, disk_end )
count -= (i+1)
pairs += count
if pairs > 10000000:
return -1
return pairs
实例:给定 [3, 0, 1, 6],磁盘半径如下所示:
disk0 ------- start= -3, end= 3
disk1 . start= 1, end= 1
disk2 --- start= 1, end= 3
disk3 ------------- start= -3, end= 9
index 3210123456789 (digits left of zero are -ve)
intervals = [(-3, 3), (-3, 9), (1, 1), (1,3)]
starts = [-3, -3, 1, 1]
the loop order will be: disk0, disk3, disk1, disk2
0th loop:
by the end of disk0, 4 disks have started
one of which is disk0 itself
none of which could have already been counted
so add 3
1st loop:
by the end of disk3, 4 disks have started
one of which is disk3 itself
one of which has already started to the left so is either counted OR would not overlap
so add 2
2nd loop:
by the end of disk1, 4 disks have started
one of which is disk1 itself
two of which have already started to the left so are either counted OR would not overlap
so add 1
3rd loop:
by the end of disk2, 4 disks have started
one of which is disk2 itself
two of which have already started to the left so are either counted OR would not overlap
so add 0
pairs = 6
to check: these are (0,1), (0,2), (0,2), (1,2), (1,3), (2,3),