【剑指offer】37.数字在排序数组中出现的次数

题目

统计一个数字在排序数组中出现的次数。


分析

由于题目中说明数组为有序数组,在该题中使用二分查找k。主要思路如下:

  1. 数组为空和数组有一个元素并且k与该元素不等,则直接返回0;
  2. 数组有一个元素并且k与该元素相等,则直接返回1;
  3. 否则启用二分查找,若找不到k则直接返回0;
  4. 若找到k在数组中位置,并分别向左和向右查找k,判断是否包含重复的k,并计数;

github链接:JZ37-数字在排序数组中出现的次数


C++代码

#include 
#include 
using namespace std;

class Solution {
	public:
	    int GetNumberOfK(vector<int> data ,int k) {
			int size = data.size();
			if(size == 0){
				return 0;
			}
			
			if(size == 1 && data[0] == k){
				return 1;
			}else if(size == 1 && data[0] != k){
				return 0;
			}
			
			// 有序数组利用二分查找k在数组中的下表 
			int index = this->Find(data,k);
			
			// 若index为-1,则表示数组中不包括k 
			if(index == -1){
				return 0;
			}
			
			// 向左扫描查看是否有重复元素
			int cnt = 1;
			for(int i = index-1 ; i >= 0 ; i--){
				if(data[i] == k){
					cnt++;
				}else{
					break;
				}
			}
			// 向右扫描查看是否有重复元素
			for(int i = index+1 ; i < size ; i++){
				if(data[i] == k){
					cnt++;
				}else{
					break;
				}
			}
			return cnt;
	    }
	    
	    int Find(vector<int> data ,int k){
	    	int low = 0;
	    	int high = data.size() - 1;
	    	int mid;
	    	while(low <= high){
	    		mid = (low + high) / 2;
	    		if(data[mid] > k){
	    			high = mid - 1;
				}else if(data[mid] < k){
					low = mid + 1;
				}else{
					break;
				}
			}
			// 若是low与high相等了,仍未找到k则数组里没有k 
			if(data[mid] != k){
				mid = -1;
			}
			return mid;
		}
};

int main()
{
	int n,k;
	while(cin>>n>>k){
		vector<int> array(n);
		for(int i = 0 ; i < n ; i++){
			cin>>array[i];
		}
		Solution s;
		cout<<s.GetNumberOfK(array,k);
	}
	
	return 0;
}

你可能感兴趣的:(#,剑指offer题解)