题目:

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

思路:

1、顺序遍历

顺序扫描一遍数组,统计该数字出现的次数。

时间复杂度:O(n)

2、二分查找

假设我们需要找的数字是k,那么就需要找到数组中的第一个k和最后一个k出现的位置。

如何通过二分查找得到第一个k的位置呢?

取数组中间的数字与k作比较,

如果该数字比k大,那么k只能出现在前半部分,那么下一轮只能在前半部分找;

如果该数字比k小,那么k只能出现在后半部分,那么下一轮只能在后半部分找;

如果该数字等于k,需要判断这是不是第一个k,如果该数字的前一个数字不是k,那么该数字就是第一个k,否则需要在前半部分继续寻找第一个k;

寻找最后一个k的方法与寻找第一个k的方法一样。

代码:

#include <iostream>

using namespace std;

int getFirstK(int* data,int k,int start,int end){
while(start<=end){
int mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid>0 && data[mid-1]!=k) || mid==0)
return mid;
else
end=mid-1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
} int getLastK(int* data,int length,int k,int start,int end){
while(start<=end){
int mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
return mid;
else
start=mid+1;
}
else if(data[mid]<k)
start=mid+1;
else
end=mid-1;
}
return -1;
} int getNumberOfK(int* data,int length,int k){
if(data==NULL || length<=0)
return 0;
int first=getFirstK(data,k,0,length-1);
int last=getLastK(data,length,k,0,length-1);
cout<<first<<" "<<last<<endl;
if(first!=-1 && last!=-1)
return last-first+1;
return 0;
} int main()
{
int A[]={1,2,3,3,3,3,4,5};
int len=sizeof(A)/sizeof(A[0]);
int k=3;
cout << getNumberOfK(A,len,k) << endl;
return 0;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/70610bf967994b22bb1c26f9ae901fa2?rp=2

AC代码:

class Solution {
public:
int GetNumberOfK(vector<int> data,int k) {
int len=data.size();
if(len<=0)
return 0;
int first=getFirstK(data,k,0,len-1);
int last=getLastK(data,len,k,0,len-1); if(first!=-1 && last!=-1)
return last-first+1;
return 0;
} int getFirstK(const vector<int> &data,int k,int start,int end){
int mid;
while(start<=end){
mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid>0 && data[mid-1]!=k) || mid==0)
return mid;
else
end=mid-1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
} int getLastK(const vector<int> &data,int length,int k,int start,int end){
int mid;
while(start<=end){
mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
return mid;
else
start=mid+1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
}
};

最新文章

  1. java 使用正则表达式过滤HTML中标签
  2. 路径分析之NetworkX实例
  3. 传感器之超声波测距HC-SR04
  4. Gym 100818G (模拟退火)
  5. 利用Apache Ant编译Hadoop2.6.0-eclipse-plugin
  6. Android Application 深入分析
  7. 2016/7/7 自定义函数copy
  8. Multiple
  9. UML--一些图
  10. List接口实现类-ArrayList、Vector、LinkedList集合深入学习以及源代码解析
  11. eclipse的调试方法的简单介绍
  12. bundle export fail
  13. QT信号和槽
  14. 目标检测 非极大值抑制(Non-Maximum Suppression,NMS)
  15. 初学python之路-day09
  16. jquery:input操作
  17. 转://Oracle 高可用技术与云基础架构
  18. Vue.JS React 精彩文章汇总
  19. java面试题:jvm
  20. [Issue]git做rebase时,弹出编辑器为nano,不会使用

热门文章

  1. 字符串处理strcpy strcat函数的用法
  2. Loadrunner脚本开发规范
  3. Jenkins配置agent
  4. NOIP2011 D1 T2选择客栈
  5. 初拾Java(问题二:缺类异常,无法编译)
  6. Highcharts实现走势图
  7. 51Nod1140 矩阵相乘的结果
  8. SCOI2011 棘手的操作
  9. [BZOJ4517][SDOI2016]排列计数(错位排列)
  10. 【最小表示法】BZOJ2882-工艺