码迷,mamicode.com
首页 > 其他好文 > 详细

数据流基本问题--确定频繁元素

时间:2015-05-21 22:43:27      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:频繁元素   过半元素   数据流   

下面可以谈论下如何求频繁元素的一个问题。

一、问题定义

如果一个数据流技术分享,其中m为数据流的大小,技术分享。我们可以定义每个元素出现的次数为技术分享,其中技术分享为第i个元素出现的次数。容易得出:技术分享

如果给定参数k,我们想求出所有出现次数超过m/k的元素。也就是输出集合:技术分享。下面我们先从一个简单特例入手,对这个问题进行分析和解决。

二.简单情况

有个经典的过半元素查找问题,在编程之美里面也有分析(寻找发帖水王)。就是说给定一个数组,找出出现次数超过一半的元素。对于这个问题一个比较好的做法就是不断删除两个不同的元素,最终剩下的元素就是所要求的元素。使用一个变量ans作为候选。该方法时间复杂度为O(n),空间复杂度为O(1)。具体实现如下:

int majority_element(vector<int>nums) {
	int len=nums.size,count=0,ans=0;
	for(int i=0;i<len;i++){
		if(count==0){
			ans=nums[i];
			count++;
		}else{
			if(ans==nums[i]){
				count++;
			}else{
				count--;
			}
		}
	}
	return ans;
}
三、一般情况

编程之美里面在解决了这个问题之后,提出了一个扩展问题,就是说如何找出发帖总数目的1/4的ID。一般化的情况就是我们在第一节中定义的问题。那一般化的问题如何解决呢?

该问题的解决方法就是对第二节中方法的改进。第二节中k=2,使用一个变量作为候选。这里,我们使用一个大小为k-1的变量作为候选,因为至多有k-1个元素的出现次数超过m/k,否则不符合实际情况。具体实现我们可以使用一个map,map里存放元素及其出现的次数。访问到第i个元素的时候,如果这个元素在map中,则将对应出现次数加1。否则看map的大小。如果map的大小少于k-1,我们将其添加到map中,设其出现次数为1。否则我们将map里面所有的元素次数都减一,如果某元素对应的次数为0,则从map中删去该元素。具体实现代码如下。

void frequent_element(vector<int>nums,int k) {
	map<int,int>num_cnt_map;
	for(int i=0;i<nums.size();i++){
		if(num_cnt_map.find(nums[i])!=num_cnt_map.end()){
			num_cnt_map[nums[i]]=num_cnt_map[nums[i]]+1;
		}else if(num_cnt_map.size()<k-1){
			num_cnt_map[nums[i]]=1;
		}else{
			for(map<int,int>::iterator it=num_cnt_map.begin();it!=num_cnt_map.end();it++){
				num_cnt_map[it->first]=num_cnt_map[it->first]-1;
				if(num_cnt_map[it->first]==0){
					num_cnt_map.erase(it);
				}
			}
		}
	}
}
下面我们对算法进行分析。在map中的元素次数都减一这个步骤(第9行到第14行的循环),一共减去了k(map中总共k个元素,每个元素对应次数减1)。所有元素出现的总次数为m,所以该步骤至多执行m/k次。显然任意出现次数超过m/k的元素一定最后仍留在map中。但是上述算法有个缺点就是:如果出现次数超过m/k的元素非常少,那么最终map中的某些元素不一定大于m/k。最终map中元素可能也没有k-1个。这时候我们需要对原数据流再做一次扫描,从而确定候选元素的出现次数,从而得出精确解。

四、进一步分析

我们可以通过第三节中的算法来对频繁元素出现的次数进行估计。对于任意频繁元素j,其出现次数为技术分享,最终估计值技术分享就是算法执行结束后num_cnt_map[j]。则两者有如下关系:

技术分享

如果我们知道算法处理结束时map中元素对应次数的和为技术分享,所以map中元素次数都减一这个步骤总共减去了技术分享,所以最多执行了技术分享次。则上面的不等式中的下界可以进一步提高:

技术分享

数据流基本问题--确定频繁元素

标签:频繁元素   过半元素   数据流   

原文地址:http://blog.csdn.net/dm_ustc/article/details/45895851

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!