原创博文,转载请注明出处!


# 题目

# 思路

利用二分查找法,查找元素k在排序数组中第一次出现的位置m及最后一次出现的位置n,m-n+1即为元素k再排序数组中出现的次数。

      二分查找法在数组中找到第一个k的思路:先拿数组中间元素mid和查找元素k比较,如果k<mid,则第一个k只可能出现在数组的前半段;如果k>mid,则第一个k只可能出现在数组的后半段;如果k=mid,则先判断中间元素是不是第一个k(如果mid前的元素不是k,则中间元素是第一个k;如果mid前的元素是k,则第一个k出现在数组的前半段。

二分查找法在数组中找到最后一个k的思路:先拿数组中间元素mid和查找元素k比较,如果k<mid,则最后一个元素k只可能出现在数组的前半段;如果k>mid,则最后一个元素k只可能出现在数组的后半段;如果k=mid,则先判断中间元素是不是最后一个k(如果mid后的元素不是k,则中间元素是最后一个k;如果mid后的元素是k,则最后一个k出现在数组的后半段。

# 代码

  1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 class Solution {
6 public:
7 // 查找元素k在有序数组中出现的次数
8 int GetNumberOfK(vector<int> data ,int k)
9 {
10 // 特殊输入
11 if(data.size() == 0)
12 return 0;
13 cout<<data.size()<<endl;
14
15 // 在有序数组中查找k第一次出现的位置
16 int first = GetFirstK(data,k,0,data.size()-1);
17 cout<<first<<endl;
18
19 // 在有序数组中查找k最后一次出现的位置
20 int last = GetLastK(data,k,0,data.size()-1);
21 cout<<last<<endl;
22
23 // 计算次数
24 if(first != -1 && last != -1)
25 return last-first+1;
26
27 // 未找到元素
28 return 0;
29 }
30
31 // 二分查找法,查找第一个k的位置
32 int GetFirstK(vector<int> data,int k,int l,int r)
33 {
34 // 递归出口
35 if(l>r)
36 return -1;
37
38 int mid = (l+r)>>1;
39
40 if(k<data[mid])
41 {
42 r = mid-1;
43 }
44 else if (k>data[mid])
45 {
46 l = mid+1;
47 }
48 else
49 {
50 if((mid>0 && data[mid-1] != k) || mid == 0)
51 return mid;
52 else
53 r = mid-1;
54 }
55 return GetFirstK(data,k,l,r);
56 }
57
58 // 二分查找法,查找最后一个k的位置
59 int GetLastK(vector<int> data,int k,int l,int r)
60 {
61 if(l>r)
62 return -1;
63
64 int mid = (l+r)>>1;
65
66 if(k<data[mid])
67 r = mid-1;
68 else if(k>data[mid])
69 l = mid+1;
70 else
71 {
72 if((mid < data.size()-1 && data[mid+1]!=k) || mid == data.size()-1)
73 return mid;
74 else
75 l = mid+1;
76 }
77 return GetLastK(data,k,l,r);
78 }
79 };
80 int main()
81 {
82 cout << "二分查找法计算数字k在排序数组中出现的次数" << endl;
83 // 空数组
84 vector<int> arr1;
85 // 数组中不包含查找的数字
86 vector<int> arr2 = {1,3,5,7,9,10};
87 // 数组中包含查找的数组(出现一次)
88 vector<int> arr3 = {1,2,2,2,2,3,3,3,4,5};
89 // 数组中包含查找的数组(出现多次)
90 vector<int> arr4 = {1,2,3,4,4,4,7,8,9,10};
91 Solution solution;
92 cout<<solution.GetNumberOfK(arr1,4)<<endl;
93
94 return 10086;
95 }
96

【剑指offer】数字在排序数组中出现的次数,C++实现的更多相关文章

  1. 剑指Offer——数字在排序数组中出现的次数

    题目描述: 统计一个数字在排序数组中出现的次数. 分析: 二分变形.二分查找最左边和最右边k的位置,然后相减加一就是结果. 代码: class Solution { public: int GetNu ...

  2. 用java刷剑指offer(数字在排序数组中出现的次数)

    题目描述 统计一个数字在排序数组中出现的次数. 牛客网链接 java代码 //看见有序就用二分法 public class Solution { public int GetNumberOfK(int ...

  3. 剑指 Offer——数字在排序数组中出现的次数

    1. 题目 2. 解答 时间复杂度为 \(O(n)\) 的算法,顺序遍历数组,当该数字第一次出现时开始记录次数. class Solution { public: int GetNumberOfK(v ...

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

    因为有序 所以用二分法,分别找到第一个k和最后一个k的下标.时间O(logN) class Solution { public: int GetNumberOfK(vector<int> ...

  5. 剑指offer--34.数字在排序数组中出现的次数

    时间限制:1秒 空间限制:32768K 热度指数:209611 本题知识点: 数组 题目描述 统计一个数字在排序数组中出现的次数. class Solution { public: int GetNu ...

  6. 剑指Offer-36.数字在排序数组中出现的次数(C++/Java)

    题目: 统计一个数字在排序数组中出现的次数. 分析: 给定一个已经排好序的数组,统计一个数字在数组中出现的次数. 那么最先想到的可以遍历数组统计出现的次数,不过题目给了排序数组,那么一定是利用了排序这 ...

  7. 剑指Offer36 数字在排序数组中出现的次数

    /************************************************************************* > File Name: 36_Number ...

  8. 剑指offer38 数字在排序数组中出现的次数

    这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...

  9. 剑指offer——56在排序数组中查找数字

    题目描述 统计一个数字在排序数组中出现的次数.   题解: 使用二分法找到数k然后向前找到第一个k,向后找到最后一个k,即可知道有几个k了 但一旦n个数都是k时,这个方法跟从头遍历没区别,都是O(N) ...

  10. 剑指offer-数字在排序数组中出现的次数-数组-python

    题目描述 统计一个数字在排序数组中出现的次数.   python 内置函数 count()一行就能搞定   解题思路 二分查找到给定的数字及其坐标.以该坐标为中点,向前向后找到这个数字的 始 – 终 ...

随机推荐

  1. Swift学习笔记 - OC中关于NSClassFromString获取不到Swift类的解决方案

    在OC和Swift混编的过程中发现在OC中通过NSClassFromString获取不到Swift中的类,调研了一下发现问题所在,下面是我的解决方案: 问题的发现过程 UIViewController ...

  2. 初入spring boot(八 )Spring Data REST

    1. 什么是Spring Data REST Spring Data JPA是基于Spring Data 的Repository之上,可以将Repository自动输出为REST资源.目前Spring ...

  3. layer弹出层的关闭及父页面的刷新问题

    当在主页面执行添加或修改时,用弹出层是比较好的选择,如何关闭弹出层并对父级页面进行操作呢 首先在父级页面中打开一个添加页面(弹出层) 在添加页面的表单提交函数中添加如下代码: function for ...

  4. 分析java进程假死状况

    摘自: http://www.myexception.cn/internet/2044496.html 分析java进程假死情况 1 引言 1.1 编写目的 为了方便大家以后发现进程假死的时候能够正常 ...

  5. vc libcurl 模拟上传文件

    http://www.cnblogs.com/killbit/p/5393301.html 附上这篇文章,因为当时就已经想到了模拟上传,但是因为时间关系,所以就直接用PHP写了.现在改进一下,用VC+ ...

  6. Java循环跳转语句之 break

    生活中,我们经常会因为某些原因中断既定的任务安排.如在参加 10000 米长跑时,才跑了 500 米就由于体力不支,需要退出比赛.在 Java 中,我们可以使用 break 语句退出指定的循环,直接执 ...

  7. sass快速入门 - 笔记

    一.使用变量 1.使用$符号来标识变量. 例: $nav-color:#F90; .nav{ $width:100px; width:$width; color:$nav-color; }

  8. Java 注解(Annotation)秒懂,你可以这样学,

    文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较尊敬老罗的.至于为什么放这张图,自然是为本篇博文服务,接下来我自会说明.好了,可以开始今天的博文了. Anno ...

  9. 【转】正向代理vs反向代理

    正向代理 正向代理:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将 ...

  10. Spring框架中,在工具类或者普通Java类中调用service或dao

    spring注解的作用: 1.spring作用在类上的注解有@Component.@Responsity.@Service以及@Controller:而@Autowired和@Resource是用来修 ...