一、热词统计
搜索引擎会通过日志文件把用户每次检索使用的所有查询串都记录下来,每个查询串的长度不超过255字节。假设目前有一千万个查询记录(重复度毕竟较高,其实互异的查询串不超过三百万个;显然,一个查询串的重复度越高,也就是热门)。先要统计最热门的10个查询串,且要求使用的内存不能超过1GB.
求给出大致解决思路。
可行且高效的方法:利用哈希表保存所有的查询串并记下每个查询串的重复次数,再利用小根堆选出重复次数最多的10个查询串。
由于重复度比较高,因此事实上只有300万的query。每个query255Byte ,可以考虑把他们放进内存中,300万*255=765M,不超过1GB。因此可以用HashMap。
第一步:先对这批数据预处理(维护一个Key为query的字符串,Value 为该Query出现次数的HashTable,即hash_map(query,value))如果该字串不在Table中,那么加入该字串,并且将Vale设为1。
如果该字串在Table中,那么将该字串的计数+1。
最终我们在O (N)的时间复杂度内用Hash表完了统计。
第二步:用堆这个数据结构,找出Top K,时间复杂度为NlogK.
即借助堆结构,我们可以在log量级的时间内查找和调整/移动。
因此,维护一个K (该题目中是10)大小的小根堆,然后遍历300万的Query,
分别和根元素进行对比,采用最小堆这种数据结构代替数组,
把查找目标元素的时间复杂度降到了O(logk) ,我们最终的时间复杂度是: O (N) +N*O (logK) 。(N为 1000万,N为300万)
二、解分式不等式
试求解关于正整数n的分数不等式
整数a,b从键盘输入(a<b)
我通过枚举来解决该问题
设和变量为s,递增变量为n,两者赋初值为0。
在sa的条件循环中,根据递增变量n对s累加求和,直至出现s>b退出循环。赋值c=n,所得c为n解区间的下限。
继续在s<=b的条件循环中,根据递增变量n对s累加求和,直至出现s>b退出循环,通过赋值d=n-1,所得d为n解区间的上限。
这里解的上限是d=n-1,而不是n。(因为当分式的和大于等于上界时,此时的n不满足原式,小于的要求,所以减一)
运行结果:
请输入正整数a,b(a<b):2018,2019
满足不等式的正整数n为:1021432 <=n<=1022442
#include<stdio.h>
#include<math.h>
void main(){
long a,b,c,d,n;
double s;//s代表不等式和
/* a,b表示不等式的上界和下界*/
/*c表示n的上界,d表示n的上界*/
/* n代表项数*/
printf(" 请输入正整数a,b(a<b):");
scanf("%ld,%ld",&a,&b);
n=0,s=0;
while(s<=a){
n+=1;
s=s+sqrt(n)/(n+1);
}
c=n;
do{
n=n+1;
s=s+sqrt(n)/(n+1);
}
while(s<=b);
d=n-1;
printf(" 满足不等式的正整数n为:%ld <=n<=%ld\n",c,d);
}