题目:
统计一个数字在排序数组中出现的次数。
思路:
看到排序数组,又需要遍历,首先想到二分查找,过程中非科班生基础薄弱暴露无遗,本篇可能罗里吧嗦,因为记录了完整填坑历程,适合和博主一样的菜鸟看。。。(tips:所有代码博主是在jupyter里敲的,勿犯眼高手低的毛病建议copy过去自己试一下)
方法一:
class Solution:
def test_in_class():
print('test_in_class')
def biSearch(self, array, k):
low = 0
high = len(array) - 1
#类方法和普通方法的调用
Solution.test_in_class()
test_out_class()
while(low <= high):#跳出时low>high
mid = low + (high - low)//2
if k == array[mid]:
return mid
if array[mid] > k:
high = mid - 1
if array[mid] < k:
low = mid + 1
return low
def test_out_class():
print('test_out_class')
if __name__ == '__main__':
a = Solution()
print(a.biSearch([1,2],2))
由此可以想到搜索k-0.5和k+0.5这两个
确定数应该插入的位置,然后相减即可,如[1,2,2,2,3,4]查找1.5和2.5会返回2和3的位置索引,即在这两处插入,直接相减即可:
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
#搜索k-0.5和k+0.5这两个确定数应该插入的位置
return self.biSearch(data, k+0.5) - self.biSearch(data, k-0.5)
def biSearch(self, data, k):
low = 0
high = len(data) - 1
while(low <= high):
mid = low + (high - low)//2
if data[mid] > k:
high = mid - 1
if data[mid] < k:
low = mid + 1
return low
方法二:
一行代码面试官直接录取有木有(手动滑稽)
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
return data.count(k);
方法三:
查找第一次k出现的位置 和 最后一次k出现的位置,相减。
摸索的二分查找三部曲:
derection:从左往右,考虑上溢出(need:low < len(data)),考虑输入小数时找不到(need:data[low]==k),return low
target:第一次k出现的位置,即找大于等于k的第一个数
method:不满足(data[mid]<k)则继续前进
class Solution:
def GetNumberOfK(self, data, k):
# write code here
left = self.getFirst(data,k)
right = self.getLast(data,k)
#返回左右下标间k值的个数,都找不到返回0
return right - left + 1 if left != -1 and right != -1 else 0
#返回数组data中第一个值为k的下标,找不到为-1
def getFirst(self,data, k):
low = 0
high = len(data) - 1
while(low<=high):
#从左向右,考虑上溢出(need:low < len(data)),考虑小数时找不到(need:data[low]==k),return low
#target:找大于等于k的第一个数
#method:不满足(data[mid]<k)则继续前进
mid = low + (high - low)//2
if data[mid] < k:
low = mid + 1
else:
high = mid - 1
return low if low < len(data) and data[low] == k else -1
#返回数组data中最后一个值为k的下标,找不到为-1
def getLast(self,data, k):
low = 0
high = len(data) - 1
while(low<=high):
#从右向左,考虑下溢出(need:high > -1),考虑小数时找不到(need:data[high]==k),return high
#target:找小于等于k的第一个数
#method:不满足(data[mid]>k)则继续前进
mid = low + (high - low)//2
if data[mid] > k:
high = mid - 1
else:
low = mid + 1
return high if high > -1 and data[high] == k else -1
#用如下数组依次测试
#data = [1,2,2,2,3,4,5]
#data = [1,3,3,3,3,4,5]
#data = [3]
#a = Solution()
#print(a.GetNumberOfK(data, 3))