题目:

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

思路:

1、顺序遍历

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

时间复杂度:O(n)

2、二分查找

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

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

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

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

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

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

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

代码:

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int getFirstK(int* data,int k,int start,int end){
  6. while(start<=end){
  7. int mid=start+((end-start)>>1);
  8. if(data[mid]==k){
  9. if((mid>0 && data[mid-1]!=k) || mid==0)
  10. return mid;
  11. else
  12. end=mid-1;
  13. }
  14. else if(data[mid]>k)
  15. end=mid-1;
  16. else
  17. start=mid+1;
  18. }
  19. return -1;
  20. }
  21.  
  22. int getLastK(int* data,int length,int k,int start,int end){
  23. while(start<=end){
  24. int mid=start+((end-start)>>1);
  25. if(data[mid]==k){
  26. if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
  27. return mid;
  28. else
  29. start=mid+1;
  30. }
  31. else if(data[mid]<k)
  32. start=mid+1;
  33. else
  34. end=mid-1;
  35. }
  36. return -1;
  37. }
  38.  
  39. int getNumberOfK(int* data,int length,int k){
  40. if(data==NULL || length<=0)
  41. return 0;
  42. int first=getFirstK(data,k,0,length-1);
  43. int last=getLastK(data,length,k,0,length-1);
  44. cout<<first<<" "<<last<<endl;
  45. if(first!=-1 && last!=-1)
  46. return last-first+1;
  47. return 0;
  48. }
  49.  
  50. int main()
  51. {
  52. int A[]={1,2,3,3,3,3,4,5};
  53. int len=sizeof(A)/sizeof(A[0]);
  54. int k=3;
  55. cout << getNumberOfK(A,len,k) << endl;
  56. return 0;
  57. }

在线测试OJ:

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

AC代码:

  1. class Solution {
  2. public:
  3. int GetNumberOfK(vector<int> data,int k) {
  4. int len=data.size();
  5. if(len<=0)
  6. return 0;
  7. int first=getFirstK(data,k,0,len-1);
  8. int last=getLastK(data,len,k,0,len-1);
  9.  
  10. if(first!=-1 && last!=-1)
  11. return last-first+1;
  12. return 0;
  13. }
  14.  
  15. int getFirstK(const vector<int> &data,int k,int start,int end){
  16. int mid;
  17. while(start<=end){
  18. mid=start+((end-start)>>1);
  19. if(data[mid]==k){
  20. if((mid>0 && data[mid-1]!=k) || mid==0)
  21. return mid;
  22. else
  23. end=mid-1;
  24. }
  25. else if(data[mid]>k)
  26. end=mid-1;
  27. else
  28. start=mid+1;
  29. }
  30. return -1;
  31. }
  32.  
  33. int getLastK(const vector<int> &data,int length,int k,int start,int end){
  34. int mid;
  35. while(start<=end){
  36. mid=start+((end-start)>>1);
  37. if(data[mid]==k){
  38. if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
  39. return mid;
  40. else
  41. start=mid+1;
  42. }
  43. else if(data[mid]>k)
  44. end=mid-1;
  45. else
  46. start=mid+1;
  47. }
  48. return -1;
  49. }
  50. };

(剑指Offer)面试题38:数字在排序数组中出现的次数的更多相关文章

  1. 【剑指offer】题目38 数字在排序数组中出现的次数

    思路: 应该是用二分查找分别找到该数字第一次和最后一次出现的位置,相减即可.O(logn) int findLeft(int a[], int n, int num) { , r = n - ; wh ...

  2. 剑指Offer - 九度1349 - 数字在排序数组中出现的次数

    剑指Offer - 九度1349 - 数字在排序数组中出现的次数2013-11-23 00:47 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n, ...

  3. 剑指offer(37)数字在排序数组中出现的次数。

    题目描述 统计一个数字在排序数组中出现的次数. 题目分析 这题用暴力解也可以过,不过面试官肯定期待更好的解法. 查找我们最熟悉的就是二分查找了,不过二分查找查找的数在数组中只有一个,我们这里却有很多个 ...

  4. 剑指offer三十七之数字在排序数组中出现的次数

    一.题目 统计一个数字在排序数组中出现的次数. 二.思路 解法一:遍历数组计数 解法二:考虑到时有序数组,所以采用分查找,找到第一个K 和 最后一个K的位置, 二者相减. 三.代码 解法一: publ ...

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

      题目描述:   统计一个数字在排序数组中出现的次数.例如,输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于数字3在该数组中出现了4次,所以函数返回4.   解题思路:   既然输入的数 ...

  6. 剑指offer37:统计一个数字在排序数组中出现的次数

    1 题目描述 统计一个数字在排序数组中出现的次数. 2 思路和方法 (1)查找有序数组,首先考虑使用二分查找,使时间复杂度为O(log n).更改二分查找的条件,不断缩小区间,直到区间头和区间尾均为k ...

  7. 剑指offer: 38 数字在排序数组中出现的次数

    题目描述 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5} 和数字3,输出4. 思路如下 1. 预估时间复杂度,最复杂情况是,顺序扫描,统计K出现的次数,时间复杂 ...

  8. 【Offer】[53-1] 【数字在排序数组中出现的次数】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 统计一个数字在排序数组中出现的次数.例如,输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出 ...

  9. 剑指offer——面试题4:二维数组中的查找

    // 面试题4:二维数组中的查找 // 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按 // 照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个 // 整数 ...

  10. 剑指Offer面试题:2.二维数组中的查找

    一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

随机推荐

  1. bzoj 1112 treap树

    思路:我们只要check一遍每个长度为k的区间就好啦,对于一个区间来说的最优值显然是中位数,我们显然要动态求 第k大,所以需要一个二叉搜索树,用treap就好啦. #include<bits/s ...

  2. Java 8 对 List<List<String>> 排序

    Java 8 对 List<List> 排序 import java.util.ArrayList; import java.util.List; import java.util.str ...

  3. docker export import后,导入镜像,启动时的错误,Error response from daemon: No command specified

    Docker的流行与它对容器的易分享和易移植密不可分,用户不仅可以把容器提交到公共服务器上,还可以把容器导出到本地文件系统中.同样,我们也可以把导出的容器重新导入到Docker运行环境中.Docker ...

  4. scrapy保存csv文件有空行的解决方案

    比如现在我有一个名为test的爬虫,运行爬虫后将结果保存到test.csv文件 默认情况下,我执行scrapy crawl test -o test.csv ,得到的结果可能就是下面这种情况,每两行中 ...

  5. 从JDBC看Mybatis的设计

    Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法. 六 ...

  6. FastReport.Net使用:[27]样式使用

    样式设置与使用 1.打开样式设置界面,通过 报表->样式 来打开. 2.样式设置包含:边框,填充,字体和文本颜色.假如不需要某项设置,可将其选择框去掉. 3.设置好样式后,将标题的style设置 ...

  7. loj2480 [CEOI2017]One-Way Streets 边双+树上差分

    边双无法确定 缩完边双就是一棵树 树上差分随意弄一下吧... #include <vector> #include <cstdio> #include <cstring& ...

  8. BZOJ1509 [NOI2003]逃学的小孩 树型DP

    题目: 分析: 首先明确我们是要求 min(dist[C][A],dist[C][B])+dist[A][B]. 我们把C当成树根,第一我们可以发现min里面取dist[C][A]或者dist[C][ ...

  9. python爬虫我是斗图之王

    python爬虫我是斗图之王 本文会以斗图啦网站为例,爬取所有表情包. 阅读之前需要对线程池.连接池.正则表达式稍作了解. 分析网站 页面url分析 打开斗图啦网站,简单翻阅之后发现最新表情每页包含的 ...

  10. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...