【剑指offer之数字在排序数组中出现的次数】

来源:互联网 发布:基价的算法和作用 编辑:程序博客网 时间:2024/06/06 19:14

【题目链接】:click here~~ 

【题目描述】:

题目描述:
统计一个数字在排序数组中出现的次数。
输入:

每个测试案例包括两行:

第一行有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
【思路1】:

采用计数数组记录每一个元素出现的次数,查询的时候输出即可。

代码;

int a[maxn],c[maxn];int main(){   // freopen("in.txt","r",stdin);    ios::sync_with_stdio(false);    int n,m,v;    while(cin>>n)    {        memset(c,0,sizeof(c));        for(int i=0; i<n; ++i)        {            cin>>a[i];            c[a[i]]++;        }        cin>>m;        while(m--)        {            cin>>v;            printf("%d\n",c[v]);        }    }    return 0;} /**************************************************************    Problem: 1349    User: herongwei    Language: C++    Result: Accepted    Time:800 ms    Memory:9328 kb****************************************************************/
【思路2】:数组有序,对于每一个查询的元素,考虑到只要找到第一个出现的位置和最后出现的位置,后者减去前者即为答案,我们手写STL的库函数lower_bound,upper_bound函数,效率果然较快,代码如下:

#pragma comment(linker,"/STACK:102400000,102400000")#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <set>#include <stack>#include <math.h>#include <map>#include <queue>#include <deque>#include <vector>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 1e6+10;const LL MOD = 999999997;int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};/*Super waigua */inline int read(){    int  c=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}    return c*f;}int a[maxn],c[maxn];int find_lower_bound(int a[],int n,int k,int begin,int end){    if(begin>end) return -1;    int mid_index=(begin+end)/2;    int mid_value=a[mid_index];    if(mid_value == k)    {        if(mid_index>0 &&a[mid_index-1]!=k || mid_index==0) return mid_index; /*找到当前k*/            else end=mid_index-1;/*前一位为k*/    }    else if(mid_value>k) end=mid_index-1;    else begin= mid_index+1;    return find_lower_bound(a,n,k,begin,end);}int find_upper_bound(int a[],int n,int k,int begin,int end){    if(begin>end) return -1;    int mid_index=(begin+end)/2;    int mid_value=a[mid_index];    if(mid_value == k)    {        if(mid_index < n-1 &&a[mid_index+1]!=k || mid_index== n-1) return mid_index; /*找到当前k*/            else begin=mid_index+1;/*后一位为k*/    }    else if(mid_value<k) begin=mid_index+1;    else end= mid_index-1;    return find_upper_bound(a,n,k,begin,end);}int Get_numberof_k(int a[],int n,int k){    int num = 0;    if(a !=NULL && n>0)    {        int first  = find_lower_bound(a,n,k,0,n-1);        int last   = find_upper_bound(a,n,k,0,n-1);        if(first >-1 && last>-1)        num=last - first+1;    }    return num;}int main(){  //  freopen("in.txt","r",stdin);    //ios::sync_with_stdio(false);    int n,m,v;    while(~scanf("%d",&n))    {        memset(c,0,sizeof(c));        for(int i=0; i<n; ++i) a[i]=read();        m=read();        while(m--){ v=read();printf("%d\n",Get_numberof_k(a,n,v));}    }    return 0;}/**************************************************************    Problem: 1349    User: herongwei    Language: C++    Result: Accepted    Time:460 ms    Memory:9332 kb****************************************************************/



参考:http://zhedahht.blog.163.com/



1 0
原创粉丝点击