剑指offer-数字在排序数组中出现的次数
题目描述
统计一个数字在排序数组中出现的次数。
解题思路
既然看到排序数组,首先想到用二分查找法找数字。那么可以分别二分查找该数字出现的首序数和尾序数,这样便可得到总次数。以找数字首序数为例,首先判断start与end的大小,若start>end,说明数组中没有找到k,返回-1。然后比较中间数字data[mid]与要查找数字k的大小:
- data[mid]与k相等:若mid为0,则直接返回首序数为0。否则比较data[mid-1]与k的大小,若相等,则说明前面还有k,在前半部分继续二分查找;若不等则说明mid即为首序数
- data[mid]小于k:中间数字小于k,说明k在后半部分,在后半部分继续二分查找
- data[mid]大于k:中间数字大于k,说明k在前半部分,在前半部分继续二分查找
同样的思想可以写出二分查找数字尾序数。
代码
1 class Solution { 2 public: 3 int GetNumberOfK(vector<int> data ,int k) { 4 int len = data.size(); 5 int first = GetFirst(data, k, 0, len-1); 6 int last = GetLast(data, k, 0, len-1); 7 if(first != -1&&last != -1) 8 return last-first+1; 9 return 0; 10 } 11 int GetFirst(vector<int> data ,int k, int start, int end){ 12 if(start > end) 13 return -1; 14 int mid = (start+end)/2; 15 if(data[mid] == k){ 16 if(mid == 0) 17 return 0; 18 else if(data[mid-1] != k) 19 return mid; 20 else 21 return GetFirst(data, k, start, mid-1); 22 } 23 else if(data[mid] < k) 24 return GetFirst(data, k, mid+1, end); 25 else 26 return GetFirst(data, k, start, mid-1); 27 } 28 int GetLast(vector<int> data ,int k, int start, int end){ 29 if(start > end) 30 return -1; 31 int mid = (start+end)/2; 32 if(data[mid] == k){ 33 int len = data.size(); 34 if(mid == len-1) 35 return len-1; 36 else if(data[mid+1] != k) 37 return mid; 38 else 39 return GetLast(data, k, mid+1, end); 40 } 41 else if(data[mid] < k) 42 return GetLast(data, k, mid+1, end); 43 else 44 return GetLast(data, k, start, mid-1); 45 } 46 };