【问题标题】:How to count the number of unique numbers in sorted array using Binary Search?如何使用二进制搜索计算排序数组中唯一数字的数量?
【发布时间】:2020-08-14 22:40:22
【问题描述】:

我正在尝试使用二进制搜索来计算排序数组中唯一数字的数量。我需要从一个数字到下一个数字的变化边缘来计算。我正在考虑在不使用递归的情况下这样做。有迭代方法吗?

def unique(x):
    start = 0
    end = len(x)-1
    count =0
    # This is the current number we are looking for
    item = x[start]

    while start <= end:
        middle = (start + end)//2
        
        if item == x[middle]:
            start = middle+1
            
        elif item < x[middle]:
            end = middle -1
        
        #when item item greater, change to next number
        count+=1

    # if the number
    return count
    
unique([1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,5,5])

谢谢。

编辑:即使 o(n) 忽略了运行时优势,我的二分搜索缺少什么?不寻找实际物品时会令人困惑。我该如何解决这个问题?

【问题讨论】:

  • 这不是递归的。但我不确定它是否有效,你永远不会改变item
  • 在你的例子中它返回5,正确答案是3。
  • 它不是计算唯一值,而是计算找到第一个元素所需的二分搜索迭代次数。
  • @Barmar 是的,我说我正在寻找一种迭代方法。我固定了返回值。是的,我知道这是错误的,这就是我在这里发帖的原因。
  • 似乎 BS 方法的复杂性是 O(klogn) 其中 n 是数组大小,k 是唯一项的数量。当 k 与 n 相当时,时间变为 O(nlogn) - 肯定比线性扫描慢

标签: python python-3.x algorithm binary-search


【解决方案1】:

利用二分搜索的工作代码(给定示例返回 3)。

正如 cmets 中所讨论的,复杂度约为 O(k*log(n)),其中 k 是唯一项目的数量,因此与 n 相比,这种方法当 k 较小时效果很好,并且可能会比线性扫描更差k ~ n的情况

def countuniquebs(A):
    n = len(A)
    t = A[0]
    l = 1
    count = 0
    while l < n - 1:
        r = n - 1
        while l < r:
            m = (r + l) // 2
            if A[m] > t:
                r = m
            else:
                l = m + 1
        count += 1
        if l < n:
            t = A[l]
    return count

print(countuniquebs([1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,5,5]))

【讨论】:

    【解决方案2】:

    我不太会称它为“使用二进制搜索”,但这种二进制分治算法在 O(k*log(n)/log(k)) 时间内工作,这比重复二进制搜索,永远不会比线性扫描差:

    def countUniques(A, start, end):
        len = end-start
        if len < 1:
            return 0
        if A[start] == A[end-1]:
            return 1
        if len < 3:
            return 2
        mid = start + len//2
        return countUniques(A, start, mid+1) + countUniques(A, mid, end) - 1
    
    A = [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,5,5,5,5,5,5,5,5]
    print(countUniques(A,0,len(A)))
    

    【讨论】:

    • 这是一个很棒的解决方案。你能解释一下为什么运行时最终是 O(k*log(n)/log(k)) 吗?这似乎是正确的,因为随着 k 接近 N,运行时接近 O(N)。
    猜你喜欢
    • 1970-01-01
    • 2017-11-18
    • 2022-07-07
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    相关资源
    最近更新 更多