(剑指Offer)面试题38:数字在排序数组中出现的次数
题目:
统计一个数字在排序数组中出现的次数。
思路:
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;
}
};
(剑指Offer)面试题38:数字在排序数组中出现的次数的更多相关文章
- 【剑指offer】题目38 数字在排序数组中出现的次数
思路: 应该是用二分查找分别找到该数字第一次和最后一次出现的位置,相减即可.O(logn) int findLeft(int a[], int n, int num) { , r = n - ; wh ...
- 剑指Offer - 九度1349 - 数字在排序数组中出现的次数
剑指Offer - 九度1349 - 数字在排序数组中出现的次数2013-11-23 00:47 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n, ...
- 剑指offer(37)数字在排序数组中出现的次数。
题目描述 统计一个数字在排序数组中出现的次数. 题目分析 这题用暴力解也可以过,不过面试官肯定期待更好的解法. 查找我们最熟悉的就是二分查找了,不过二分查找查找的数在数组中只有一个,我们这里却有很多个 ...
- 剑指offer三十七之数字在排序数组中出现的次数
一.题目 统计一个数字在排序数组中出现的次数. 二.思路 解法一:遍历数组计数 解法二:考虑到时有序数组,所以采用分查找,找到第一个K 和 最后一个K的位置, 二者相减. 三.代码 解法一: publ ...
- 【剑指Offer】37、数字在排序数组中出现的次数
题目描述: 统计一个数字在排序数组中出现的次数.例如,输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于数字3在该数组中出现了4次,所以函数返回4. 解题思路: 既然输入的数 ...
- 剑指offer37:统计一个数字在排序数组中出现的次数
1 题目描述 统计一个数字在排序数组中出现的次数. 2 思路和方法 (1)查找有序数组,首先考虑使用二分查找,使时间复杂度为O(log n).更改二分查找的条件,不断缩小区间,直到区间头和区间尾均为k ...
- 剑指offer: 38 数字在排序数组中出现的次数
题目描述 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5} 和数字3,输出4. 思路如下 1. 预估时间复杂度,最复杂情况是,顺序扫描,统计K出现的次数,时间复杂 ...
- 【Offer】[53-1] 【数字在排序数组中出现的次数】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 统计一个数字在排序数组中出现的次数.例如,输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出 ...
- 剑指offer——面试题4:二维数组中的查找
// 面试题4:二维数组中的查找 // 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按 // 照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个 // 整数 ...
- 剑指Offer面试题:2.二维数组中的查找
一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...
随机推荐
- java总结(一)(变量类型)
java代码运行原理 需要注意 公共类类名必须和文件名相同 一个文件可以有好几个类,编译生成n个类文件名 chcp 65001----utf8 936----GBK 437----美国英语 文档注释必 ...
- mysql 事务回滚
begindeclare t_error integer default 0; //添加变量t_error并赋初始值为0declare continue handler for sqlexcepti ...
- Ngnix的日志管理和用定时任务完成日志切割
一.日志管理 先来看看ngnix的配置文件的server段 接下来我们解释一下默认格式的具体意思 #log_format main '$remote_addr(远程IP) - $remote_user ...
- 转:xxe attack学习
小结 1.http包发送类型:content-type:text/xml2.xxe漏洞非常危险, 因为此漏洞会造成服务器上敏感数据的泄露,和潜在的服务器拒绝服务攻击.要去校验DTD(document ...
- docker chown: changing ownership of '/var/lib/XXX': Permission denied
Links: 1.entos7下docker Permission denied 2.查看 SELinux状态及关闭SELinux 方法: 1.查看SELinux状态sestatus -vgetenf ...
- windows 10 下安装python 2.7
下载msi的安装包: https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi [incorrect] PS C:\Python27> . ...
- 推荐2本学习java书和PDF
推荐2本学习java书和PDF下载地址 <深入理解Java虚拟机:JVM高级特性与最佳实践>共分为五大部分,围绕内存管理.执行子系统.程序编译与优化.高效并发等核心主题对JVM进行了全面而 ...
- (转)Ubuntu 16.04 安裝Docker(PS:本文适用amd64位的ubuntu系统)
1.前置安裝,確保你的系統是64位 $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-p ...
- Python Socket多线程并发
1.SocketServer模块编写的TCP服务器端代码 Socketserver原理图 服务端: import SocketServer #导入SocketServer,多线程并发由此类实现 cla ...
- 网络流—最大流(Edmond-Karp算法)
一.含义 从源点到经过的所有路径的最终到达汇点的所有流量和 例如: 在这个图中求源点1,到汇点4的最大流.答案为50,其中1->2->4为20 :1->4为20 :1->2-& ...