剑指Offer - 九度1349 - 数字在排序数组中出现的次数
2013-11-23 00:47
题目描述:
统计一个数字在排序数组中出现的次数。
输入:

每个测试案例包括两行:

第一行有1个整数n,表示数组的大小。1<=n <= 10^6。

第二行有n个整数,表示数组元素,每个元素均为int。

第三行有1个整数m,表示接下来有m次查询。1<=m<=10^3。

下面有m行,每行有一个整数k,表示要查询的数。

输出:
对应每个测试案例,有m行输出,每行1整数,表示数组中该数字出现的次数。
样例输入:
8
1 2 3 3 3 3 4 5
1
3
样例输出:
4
题意分析:
  题目要求在一个数组中找出一个数出现的次数,
    第一种想法,当然是一次性全部数一遍,用map之类的结构保存统计结果,之后每次就可以log n复杂度查询了。时间复杂度为O(n) + m * O(log k),k是数组中不同元素的个数,空间复杂度O(k)。问题是——数组已经排序,这个特性没用到。
    第二种想法,因为数组有序,所以每次都用二分查找找出一个数的左界和右界,然后right - left + 1即为结果。对于不存在的元素,二分当然返回-1之类的NOT_FOUND值,统计结果则为0。时间复杂度为m * O(log n),空间复杂度O(1)。
  观察题目数据范围,数组长度n最大可以到10^6,查询次数m最大才10^3,如果采取上面方法一,O(n)则占了大头,不划算。所以选方法二。
  其中bsearch_left求出target在数组a[]中的左下标,bsearch_right为右下标。这俩函数写法要小心,检查好数组指针,数据范围,左右端后才能开始二分查找。
  查找到左右下标后,rr - ll + 1即为结果;查不到左右下标的话,结果为0。
 // 652724    zhuli19901106    1349    Accepted    点击此处查看所有case的执行结果    4932KB    1913B    720MS
//
#include <cstdio>
using namespace std; int bsearch_left(const int a[], int n, int target)
{
int ll, rr, mm; if(a == NULL || n <= ){
return -;
} if(target < a[] || target > a[n - ]){
return -;
} // guarantee that a[left] < target && a[right] >= target
if(target == a[]){
return ;
} ll = ;
rr = n - ;
while(rr - ll > ){
mm = (ll + rr) / ;
if(target > a[mm]){
ll = mm;
}else{
rr = mm;
}
} if(a[rr] == target){
return rr;
}else{
return -;
}
} int bsearch_right(const int a[], int n, int target)
{
int ll, rr, mm; if(a == NULL || n <= ){
return -;
} if(target < a[] || target > a[n - ]){
return -;
} // guarantee that a[left] <= target && a[right] > target
if(target == a[n - ]){
return n - ;
} ll = ;
rr = n - ;
while(rr - ll > ){
mm = (ll + rr) / ;
if(target >= a[mm]){
ll = mm;
}else{
rr = mm;
}
} if(a[ll] == target){
return ll;
}else{
return -;
}
} int main()
{
int *a = NULL;
int i, n, m;
int target;
int ll, rr; while(scanf("%d", &n) == ){
if(n <= ){
continue;
}
a = new int[n];
for(i = ; i < n; ++i){
scanf("%d", &a[i]);
}
scanf("%d", &m);
for(i = ; i < m; ++i){
scanf("%d", &target);
ll = bsearch_left(a, n, target);
if(ll < ){
printf("0\n");
continue;
}
rr = bsearch_right(a, n, target);
if(rr < ){
printf("0\n");
continue;
}
if(rr >= ll){
printf("%d\n", rr - ll + );
}else{
printf("0\n");
}
}
delete[] a;
a = NULL;
} return ;
}

剑指Offer - 九度1349 - 数字在排序数组中出现的次数的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 九度OJ 1349 数字在排序数组中出现的次数 -- 二分查找

    题目地址:http://ac.jobdu.com/problem.php?pid=1349 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数 ...

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

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

  8. 九度oj 1349 数字在排序数组中出现的次数

    原题链接:http://ac.jobdu.com/problem.php?pid=1349 二分.. #include<algorithm> #include<iostream> ...

  9. 【剑指Offer面试编程题】题目1349:数字在排序数组中出现的次数--九度OJ

    题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小.1<=n <= 10^6. 第二行有n个整数,表示数组元素,每个元素均 ...

随机推荐

  1. TP5.0: 显示错误信息

    在TP5中,我们运行的代码有错误无法执行时,只显示页面错误,而不显示错误信息 对我我来讲是无法接受滴!!毕竟我还是个小渣渣,查看了百度,解决方案是: 在application/config,php中找 ...

  2. ubuntu 安装 deb 软件包

    参考链接地址 blog.csdn.net/kevinhg/article/details/5934462 sudo dpkg -i xxxx.deb 安装一个 Debian 软件包,如你手动下载的文件

  3. 译:Local Spectral Graph Convolution for Point Set Feature Learning-用于点集特征学习的局部谱图卷积

    标题:Local Spectral Graph Convolution for Point Set Feature Learning 作者:Chu Wang, Babak Samari, Kaleem ...

  4. sql server 拆分字符串,拆分两次(:和;)

    declare @DisciplineID int declare @paramStringVal nvarchar() declare @NPNT nvarchar() declare @Disci ...

  5. 【转】startActivityForResult和setResult详解

    startActivityForResult与startActivity的不同之处在于:1.startActivity( ) 仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startAct ...

  6. Shell编程学习之Shell编程基础(一)

    这篇随笔将要介绍关于Shell编程的基本知识,这些将会在假设你已经熟悉了Linux系统和命令行的基本知识. 构建基本脚本 你应该了解或熟悉使用Shell命令行了,但是只是使用Shell命令行的命令,有 ...

  7. 第36章 SDIO—SD卡读写测试—零死角玩转STM32-F429系列

    第36章     SDIO—SD卡读写测试 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...

  8. python中的反斜杠问题

    python本身使用 \ 来转义一些特殊字符,比如在字符串中加入引号的时候 s = 'i\'m superman' print(s) # i'm superman 为了防止和字符串本身的引号冲突,使用 ...

  9. SpringBoot学习10:springboot整合mybatis

    需求:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一个对数据库中的 t_user 表的 CRUD 的操作 1.创建maven项目,添加项目所需依赖 <!--spr ...

  10. ReplaceChar

    好吧,给个char的,替换单个字符.这样会快一些吧,这个是置换,连长度都不用了 bool ReplaceChar(char *str,const char src, const char dst){ ...