题目描述
统计一个数字在排序数组中出现的次数。例如:输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4.
思路
- 因为是一个有序数组,通过二分查找分别去找到要找数字出现的第一个位置,和最后一个位置
- 之后last-first+1即为出现的次数
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if not data or not k:
return 0
first = self.getfirst(data, k, 0, len(data) - 1)
last = self.getlast(data, k, 0, len(data) - 1)
if first > -1 and last > -1:
return last - first + 1
else:
return 0
def getfirst(self, data, k, left, right):
while left <= right:
mid = (left + right) // 2
if data[mid] > k:
right = mid - 1
elif data[mid] < k:
left = mid + 1
else:
if mid == 0 or (mid > 0 and data[mid - 1] != k):
# 如果到了最左边,就不用看是否前一个数为k了
return mid
else:
right = mid - 1 # mid-1这个位置还有k,要找第一个k的位置,把right提上来
return -1
def getlast(self, data, k, left, right):
while left <= right:
mid = (left + right) // 2
if data[mid] > k:
right = mid - 1
elif data[mid] < k:
left = mid + 1
else:
if mid == len(data) - 1 or (mid < len(data) - 1 and data[mid + 1] != k):
# 同理到了最右边,也不用看是否等于k了
return mid
else:
left = mid + 1 # mid+1这个位置还有k,要找最后一个k的位置,把left放下去
return -1
利用二分查找模板来做
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if len(data)<1:
return 0
low=0
high=len(data)-1
while low<high:
mid=low+(high-low)/2
if data[mid]<k:
low=mid+1
else:
high=mid
if data[low]!=k:
return 0
while low>0 and data[low]==data[low-1]:
low-=1
while high<len(data)-1 and data[high]==data[high+1]:
high+=1
return high-low+1
测试用例
if __name__=='__main__':
s=Solution()
numbers1=[1,2,3,3,3,3,4,5]
numbers2=[1,2,2,3]
numbers3=[3]
print(s.GetNumberOfK(numbers1,3))
print(s.GetNumberOfK(numbers2,4))
print(s.GetNumberOfK(numbers3,3))