剑指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 };

 

posted @ 2018-04-01 12:02  FlyingWarrior  阅读(178)  评论(0编辑  收藏  举报