O(logN)中的排序列表计数元素

时间:2018-10-19 06:33:21

标签: python python-3.x algorithm count time-complexity

假设我有一个排序的列表/数组 我需要在O(logN)重复中计算该列表/数组中不同数字的数量 我已经知道我需要使用某种二进制算法,但是在最坏的情况下,我无法在O(logN)重复中使用它 有什么主意吗?

2 个答案:

答案 0 :(得分:1)

使用bisect模块。

import bisect as b


arr = [1, 1, 1, 2, 2, 3, 3, 3, 3]
for x in [1, 2, 3, 0]:
    print(b.bisect_right(arr, x) - b.bisect_left(arr, x))

输出:

3
2
4
0

因此,该算法适用于您传递的任何值。如果传递的值不在列表中,则返回0。


bisect模块通过使用二进制搜索来找到用于插入给定元素的适当位置来工作。 bisect_left给出最左边的索引,而bisect_right给出任何现有值右边的索引。 通过将两者相减,我们可以获得列表中已经存在的x的值数。

由于bisect模块使用二进制搜索,因此此方法为O(log N)。

答案 1 :(得分:0)

您可以在上半部分的最后一项与下半部分的第一项相等的情况下进行分治和减法计数:

def count(l):
    if len(l) <= 1:
        return len(l)
    mid = len(l) // 2
    head, tail = l[:mid], l[mid:]
    return count(head) + count(tail) - (len(head) and len(tail) and head[-1] == tail[0])

这样:

count([2,2,3,4,4,5,6,6,6,7,8])

返回:7(因为我们有7个不同的数字:23456,{{ 1}},7