【剑指offer】数字在排序数组中出现的次数,C++实现
原创博文,转载请注明出处!
# 题目

# 思路
利用二分查找法,查找元素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++实现的更多相关文章
- 剑指Offer——数字在排序数组中出现的次数
题目描述: 统计一个数字在排序数组中出现的次数. 分析: 二分变形.二分查找最左边和最右边k的位置,然后相减加一就是结果. 代码: class Solution { public: int GetNu ...
- 用java刷剑指offer(数字在排序数组中出现的次数)
题目描述 统计一个数字在排序数组中出现的次数. 牛客网链接 java代码 //看见有序就用二分法 public class Solution { public int GetNumberOfK(int ...
- 剑指 Offer——数字在排序数组中出现的次数
1. 题目 2. 解答 时间复杂度为 \(O(n)\) 的算法,顺序遍历数组,当该数字第一次出现时开始记录次数. class Solution { public: int GetNumberOfK(v ...
- 剑指offer 数字在排序数组中出现的次数
因为有序 所以用二分法,分别找到第一个k和最后一个k的下标.时间O(logN) class Solution { public: int GetNumberOfK(vector<int> ...
- 剑指offer--34.数字在排序数组中出现的次数
时间限制:1秒 空间限制:32768K 热度指数:209611 本题知识点: 数组 题目描述 统计一个数字在排序数组中出现的次数. class Solution { public: int GetNu ...
- 剑指Offer-36.数字在排序数组中出现的次数(C++/Java)
题目: 统计一个数字在排序数组中出现的次数. 分析: 给定一个已经排好序的数组,统计一个数字在数组中出现的次数. 那么最先想到的可以遍历数组统计出现的次数,不过题目给了排序数组,那么一定是利用了排序这 ...
- 剑指Offer36 数字在排序数组中出现的次数
/************************************************************************* > File Name: 36_Number ...
- 剑指offer38 数字在排序数组中出现的次数
这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...
- 剑指offer——56在排序数组中查找数字
题目描述 统计一个数字在排序数组中出现的次数. 题解: 使用二分法找到数k然后向前找到第一个k,向后找到最后一个k,即可知道有几个k了 但一旦n个数都是k时,这个方法跟从头遍历没区别,都是O(N) ...
- 剑指offer-数字在排序数组中出现的次数-数组-python
题目描述 统计一个数字在排序数组中出现的次数. python 内置函数 count()一行就能搞定 解题思路 二分查找到给定的数字及其坐标.以该坐标为中点,向前向后找到这个数字的 始 – 终 ...
随机推荐
- Lucene 的 Scoring 评分机制
转自: http://www.oschina.net/question/5189_7707 Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分.它对用户来 ...
- 2017 ACM/ICPC Asia Regional Qingdao Online - 1011 A Cubic number and A Cubic Number
2017-09-17 17:12:11 writer:pprp 找规律,质数只有是两个相邻的立方数的差才能形成,公式就是3 * n * (n + 1) +1, 判断读入的数是不是满足 这次依然只是做了 ...
- codeforces 578c - weekness and poorness - 三分
2017-08-27 17:24:07 writer:pprp 题意简述: • Codeforces 578C Weakness and poorness• 给定一个序列A• 一个区间的poornes ...
- Python学习札记(十六) 高级特性2 迭代
参考:迭代 Note 1.如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在C.C++.Java等语言中,for循 ...
- 关于ckeditor 之 上传功能
度了很多文章,看了很多关于ckeditor配置上传功能的文章,没一个写得清楚的, 就是简单的根目录下.config.js 增加 config.filebrowserUploadUrl="/a ...
- hibernate:inverse、cascade,一对多、多对多详解
1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所 ...
- java23种设计模式之三: 适配器模式
一.适配器模式 就是个通过一个中间件转化,可以将不匹配的两件事整合到一起,把不匹配变的匹配. 二.适配器分类 1.类适配器 2.对象适配器 三. 适配器的3种组成 1.类适配器组成 1.2个接口 ...
- 二、nginx 安装目录详解
rpm -ql nginx 路径 类型 介绍 /etc/logrotate.d/nginx 配置文件 Nginx 日志轮转,用于logrotate服务日志切割 /etc/nginx /etc/ng ...
- Eclipse创建Maven聚合项目
整体架构图 1.新建父工程 新建maven父项目(用来管理jar包版本),使子系统使用同一个版本的jar包. File->New->Other->Maven Project,打包方式 ...
- 进程上下文频繁切换导致load average过高
一.问题现象 现网有两台虚拟机主机95%的cpu处于idle状态,内存使用率也不是特别高,而主机的load average达到了40多. 二.问题分析 先在主机上通过top.free.ps.iosta ...