如何使用二进制搜索计算排序数组中唯一数字的数量?
How to count the number of unique numbers in sorted array using Binary Search?
我正在尝试使用二进制搜索计算排序数组中唯一数字的数量。我需要获得从一个数字到下一个数字的变化边缘才能计数。我正在考虑在不使用递归的情况下这样做。是否有迭代方法?
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) 忽略了运行时收益,我的二分查找缺少什么?不寻找实际项目时会造成混淆。我该如何解决这个问题?
利用二进制搜索的工作代码(给定示例returns 3)。
正如评论中所讨论的那样,复杂度约为 O(k*log(n))
,其中 k 是唯一项的数量,因此这种方法在 当 k 小于 与 n 相比时效果很好,并且在 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]))
我不太会称它为“使用二进制搜索”,但是这个二进制 divide-and-conquer 算法在 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)))
我正在尝试使用二进制搜索计算排序数组中唯一数字的数量。我需要获得从一个数字到下一个数字的变化边缘才能计数。我正在考虑在不使用递归的情况下这样做。是否有迭代方法?
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) 忽略了运行时收益,我的二分查找缺少什么?不寻找实际项目时会造成混淆。我该如何解决这个问题?
利用二进制搜索的工作代码(给定示例returns 3)。
正如评论中所讨论的那样,复杂度约为 O(k*log(n))
,其中 k 是唯一项的数量,因此这种方法在 当 k 小于 与 n 相比时效果很好,并且在 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]))
我不太会称它为“使用二进制搜索”,但是这个二进制 divide-and-conquer 算法在 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)))