题目链接地址:
题目描述:
统计一个数字在排序数组中出现的次数。
输入:
每个测试案例包括两行:
第一行有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) 通过二分查找找到待查元素k在数组中的位置;
(2) 以k在数组中的位置为中心,先向左查找与k相等的元素,再向右查找与k相等的元素。
(3) 待所有查找操作完成后,即可统计出数字k在数组中出现的次数。
举个栗子,对于测试用例1 2 3 3 3 3 4 5,下面是查找3的过程:
1) 通过二分查找可以得知’3’在数组中的下标是3(数组下标从0开始);
2) 以数组的第3个元素为中心,向左查找可以得知第2个元素也是’3’,再向右查找可以得知第4个和第5个元素也是’3’;
3) 最后可以得知数字’3’在该数组中出现的次数是4。
AC代码如下:
#include<stdio.h>
#define MAX 1000001
int number[MAX];
/**
* 输入整形数组
* @param n 输入的数组大小
* @return void
*/
void inputArray(int n)
{
int i;
for(i = 0;i < n;i++)
{
scanf("%d",&number[i]);
}
}
/**
* 二分查找
* @param k 待查找的元素
* @param n 数组的长度
* @return position 待查元素在数组中的位置,如果查找不成功,则返回-1
*/
int binarySearch(int k,int n)
{
int position = -1;
int left = 0,right = n - 1;
int middle;
while(left <= right)
{
middle = (left + right) / 2;
if(k == number[middle])
{
position = middle;
break;
}
else if(k > number[middle])
{
left = middle + 1;
}
else
{
right = middle - 1;
}
}
return position;
}
/**
* 统计k在有序数组中出现的次数。以k为中心,向数组两边同时查找与k相等的元素
* @param k 待查找的元素
* @param position k在数组中的位置
* @param n 数组的长度
* @return count 数字k在有序数组中出现的次数
*/
int countKinSortArray(int k,int position,int n)
{
int count = 0;
int i = position - 1;
int j = position;
// 向数组的左边查找与k相等的元素,为了避免查找过程中出现数组越界,先判断i是否大于等于0,再让number[i]与k进行比较
while(i >= 0 && number[i] == k)
{
i--;
count++;
}
// 向数组的右边查找与k相等的元素
while(j < n && number[j] == k)
{
j++;
count++;
}
return count;
}
int main()
{
int n,m,k;
int position; // 待查元素在有序数组中的位置
int count; // 待查元素在有序数组中出现的次数
while(EOF != scanf("%d",&n))
{
inputArray(n);
scanf("%d",&m);
while(m--)
{
scanf("%d",&k);
count = 0;
position = binarySearch(k,n);
if(-1 != position)
{
count = countKinSortArray(k,position,n);
}
printf("%d\n",count);
}
}
return 0;
}
/**************************************************************
Problem: 1349
User: blueshell
Language: C++
Result: Accepted
Time:730 ms
Memory:4928 kb
****************************************************************/