统计一个数字在排序数组中出现的次数

题目描述
统计一个数字在排序数组中出现的次数。

分析
既然是有序数组,要找其中的某个元素,时间最低的就是二分查找了,关键是需要找到连续的数字的上下界,这是一个技巧,也是难点。

时间O(logn) 空间O(1)

class Solution:
    def GetNumberOfK(self, data, k):
        def binary_search_lower_bound(a, x):
            s, e = 0, len(a)-1
            mid = -1
            while s <= e:
                mid = (s + e)//2
                if a[mid] == x:
                    #如果找到左边界了,或者在往左一个元素不是x,则说明找到第一个了
                    if mid == s or a[mid-1] != x: 
                        return mid
                    else:
                    #没有找到第一个就将mid往左移一步
                        e = mid - 1
                elif a[mid] > x:
                    e = mid - 1
                else:
                    s = mid + 1
            return -1

        def binary_search_upper_bound(a, x):
            #寻找重复数字的最后一个数的位置
            s, e = 0, len(a)-1
            mid = -1
            while s <= e:
                mid = (s + e)//2
                if a[mid] == x: #关键在于这一步,假设x是有重复的
                    if mid == e or a[mid+1] != x: #找到这个边界,或者下一个元素不为x,就是边界了
                        return mid
                    else:
                        s = mid + 1 #不是边界的话,往前移动一步
                elif a[mid] > x:
                    e = mid - 1
                else:
                    s = mid + 1
            return -1
        
        
        low = binary_search_lower_bound(data, k)
        upper = binary_search_upper_bound(data, k)

        if low == -1 or upper == -1:
            return 0
        return upper - low + 1
a = [1,1,1,1,2,2,2,3,4,5,9,10]
left = binary_search_lower_bound(a, 2)
right = binary_search_upper_bound(a, 2)

print(left, right)#4 6

s = Solution().GetNumberOfK(a, 2)
print(s) #3

你可能感兴趣的:(算法)