剑指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. Socket的基本使用步骤

    Socket的基本使用步骤 一.使用Socket,首先需要导入这几个系统头文件 #import <sys/socket.h> #import <netinet/in.h> #i ...

  2. centos6.5下编译安装FFmpeg

    以下安装步骤基本来自官网,做个笔记以方便自己以后查看 http://trac.ffmpeg.org/wiki/CompilationGuide 1.安装依赖包 <span style=" ...

  3. redis hash类型

  4. WinSCP 工具

    windows 与 Linux 传文件,非常方便.安全.

  5. 下载Xcode历史版本方法

    1.打开链接:https://developer.apple.com/download/more 进入页面 2.在搜索框输入Xcode,回车搜索.如图,找到各种版本Xcode 搜索Xcode 3.双击 ...

  6. CUDA线性内存分配

    原文链接 概述:线性存储器可以通过cudaMalloc().cudaMallocPitch()和cudaMalloc3D()分配 1.1D线性内存分配 1 cudaMalloc(void**,int) ...

  7. 散度(Divergence)和旋度(Curl)

    原文链接 散度(Divergence) 散度的讨论应从向量和向量场说起.向量是数学中研究多维计算的基本概念.比如,速度可以分解为相互独立的分量,则速度就是一个多维的向量.假如空间中的每一个位置都有一个 ...

  8. 前端面试整理(HTML&CSS)

    1.行内元素和块级元素?img算什么?行内元素怎么转化为块级元素? 行内元素:和有他元素都在一行上,高度.行高及外边距和内边距都不可改变,文字图片的宽度不可改变,只能容纳文本或者其他行内元素:其中im ...

  9. motto - Express 4.x Request对象获得参数方法

    本文搜索关键字:motto express node js nodejs javascript request body request.body 1. req.param() 该方法获得参数最为方便 ...

  10. GUI测试问题汇总

    1.ajax实现的页面元素定位问题 最近在做项目的时候遇到一个问题,通过xpath定位到元素后做一个循环操作,第一循环可以正常执行,第二次循环后就报错,错误信息:Message: The elemen ...