剑指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. 使用taobao cnpm 源解决npm无法安装module问题

    npm 安装nativescript时出现异常,一直停着不动.应该是源被墙了的问题可以使用淘宝仓库,执行下面的命令: alias cnpm="npm --registry=https://r ...

  2. CentOS安装配置MongoDB

    1.下载安装包: wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.3.tgz 2.解压: tar -zxvf mongodb-l ...

  3. 2017.11.27 用Servlet在JSP中加入验证码

    登陆界面 <%@ page pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  4. a=a+(a++);b=b+(++b);计算顺序,反汇编

    a=a+(a++); 013913BC mov eax,dword ptr [a] 013913BF add eax,dword ptr [a] 013913C2 mov dword ptr [a], ...

  5. 一、初始Object-C

    一.OC概述 特点: 1没有包得概念 2关键字以@开头 3.拓展名 .m 二.第一个OC类 1,分为2个文件..m和.h文件 2. .m文件用来实现类  .h用来定义声明类 .h文件中得写法 //@i ...

  6. eclipse 插件relo使用

    1. eclipse插件安装 在线安装地址:http://relo.csail.mit.edu/update 本地配置,文件下载:http://download.csdn.net/download/s ...

  7. Spring 注解中@Resource 和 @Authwired 的区别

    @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了.@Resource有两个属性是比较重要的,分 ...

  8. loss 和accuracy的关系梳理

    最近打算总结一下这部分东西,先记录留个脚印.

  9. SpringBoot学习13:springboot异常处理方式3(使用@ControllerAdvice+@ExceptionHandle注解)

    问题:使用@ExceptionHandle注解需要在每一个controller代码里面都添加异常处理,会咋成代码冗余 解决方法:新建一个全局异常处理类,添加@ControllerAdvice注解即可 ...

  10. iOS第三方支付(支付宝)

    使用支付宝进行一个完整的支付功能,大致有以下步骤: 与支付宝签约,获得商户ID(partner)和账号ID(seller) 下载相应的公钥私钥文件(加密签名用) 下载支付宝SDK 生成订单信息 调用支 ...