(剑指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.二维数组中的查找
一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...
随机推荐
- 导出php5.4支持的数组格式,即以[]为标识符而不是以array()标识
//导出php数组,以[]为标识符而不是以array() if (!function_exists('varExport')) { //导出php数组,以[]为标识符而不是以array() funct ...
- 长安大学第四届ACM-ICPC“迎新杯”程序设计竞赛-重现赛 F - 打铁的箱子
题目描述 作为彩虹岛上最擅长打铁的人,
- CF986B Petr and Permutations [逆序对]
题目传送门 Petr and Permutations 格式难调,题面就不放了. 分析: 胡乱分析+猜测SP性质一波.然后被学长告知:“1~n的排列交换次数与逆序对的奇偶性相同.”然后就愉快地A了. ...
- Mybatis源码分析之Mapper文件解析
感觉CSDN对markdown的支持不够友好,总是伴随各种问题,很恼火! xxMapper.xml的解析主要由XMLMapperBuilder类完成,parse方法来完成解析: public void ...
- Hat's Fibonacci hdu 1250
Problem Description A Fibonacci sequence is calculated by adding the previous two members the sequen ...
- JNI介绍
JNI是在学习Android HAL时必须要面临一个知识点,如果你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官在运行Java代码的Android中有着 ...
- 在活动之间切换(显式Intent)
实验名称:在活动之间切换 实验现象:通过点击主活动的按钮进入下一个界面 使用技术:显式Intent 步骤: 1.创建一个项目,加载布局.添加一个button 2.新建一个活动. 3.修改按钮的点击事件 ...
- noip200807传纸条
试题描述: 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的 ...
- 2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询
D - 秋实大哥与战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 D ...
- 使用辗转相除法求两个数的最大公因数(python实现)
数学背景: 整除的定义: 任给两个整数a,b,其中b≠0,如果存在一个整数q使得等式 a = bq 成立,我们就说是b整除 ...