Career Cup: Map, 发帖水王

本文介绍了一种在O(n)时间内找到数组中出现频率超过1/3的元素的算法。通过使用比较操作和避免额外的空间开销,实现了一种高效的方法来解决这个问题,而不需要使用哈希表或其他标准的线性时间选择算法。

http://www.careercup.com/question?id=14099679

Design an algorithm that, given a list of n elements in an array, finds all the elements that appear more than n/3 times in the list. The algorithm should run in linear time ( n >=0 )
You are expected to use comparisons and achieve linear time. No hashing/excessive space/ and don't use standard linear time deterministic selection algo 

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef map<int, int> Map;
Map findOverNth(int arr[], int size, int n);
int main()
{
	//int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1}; 
	int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
	map<int, int>::iterator it;
	int size = sizeof(arr) / sizeof(int);
	Map map_result(findOverNth(arr, size, 3));
	for(it = map_result.begin(); it != map_result.end(); it++)
	{
		cout<<(*it).first<<endl;
	}
	return 0;
}

Map findOverNth(int arr[], int size, int n)
{
	Map a_map, result_map;
	pair<map<int, int>::iterator, bool> insert_suc;
	map<int, int>::iterator it;
	for(int i = 0; i < size; i++)
	{
		if(a_map.size() < n)
		{
			it = a_map.find(arr[i]);
			if(it != a_map.end())
			{
				(*it).second++;
			}
			else
			{
				a_map.insert(pair<int, int>(arr[i], 1));
			}
		}
		if(a_map.size() == n)
		{
			for(it = a_map.begin(); it != a_map.end();)
			{
				(*it).second--;
				if((*it).second == 0)
				{
					a_map.erase(it++);
				}
				else
					it++;
			}
		}
	}
	result_map = a_map;
	for(it = result_map.begin(); it != result_map.end(); it++)
	{
		(*it).second = 0;
	}
	for(int i = 0; i < size; i++)
	{
		it = result_map.find(arr[i]);
		if(it != result_map.end())
		{
			(*it).second++;
		}	
	}
	
	for(it = result_map.begin(); it != result_map.end();)
	{
		if((*it).second * 3 < size)
			result_map.erase(it++);
		else
			it++;
	}

	return result_map;
}
/*
#include <iostream>
#include <map>
#include <algorithm>
typedef std::map<int, int> Map;
 Map findOverNth(int arr[], int size, int n)
{
	Map ret_map; 
	typedef Map::value_type Elem; //pair<CONST int, int>
	int total = 0;
	std::for_each(arr, arr + size, [&, n](int val) 
	{
		auto ret_pair = ret_map.insert(Elem(val, 0));
		++(*ret_pair.first).second; ++ total;
		if (ret_map.size() == n)
			for (auto iter = ret_map.begin(); iter != ret_map.end(); )
			{
				--(*iter).second; -- total;
				if ((*iter).second == 0)
					ret_map.erase(iter++);
				else
					iter++;
			}
	});
	std::for_each(ret_map.begin(), ret_map.end(), [](Elem &elem) {elem.second = 0;});
	std::for_each(arr, arr + size, [&ret_map](int val) {if (ret_map.find(val) != ret_map.end()) ret_map[val] ++;});
	for (auto iter = ret_map.begin(); iter != ret_map.end(); )
	{
		if ((*iter).second <= size / n)
			ret_map.erase(iter++);
		else 
			iter++;
	}
	return ret_map;
}
using namespace std;
int main()
{
	//int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
	int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1};
	auto a_map = findOverNth(arr, sizeof(arr)/sizeof(int), 4);
	cout<<sizeof(arr)/sizeof(int)<<endl;
	//cout<<a_map.size()<<endl;
	for each(auto elem in a_map)
	{
		cout<<elem.first<<" "<<elem.second<<endl;
	}
}
*/


顺便讲讲map的功能。
这里红色标注的代码是一段正确的代码,但是看起来有些奇怪。
一开始的时候我是这样写的代码:
map<string,int> theMap;
// add something to theMap...

for(auto iter1 = theMap.begin(); iter1 != theMap.end(); ++iter1)
{
    if(iter1->second == xxx)
   {
        theMap.erase(iter1);  //#1 erase the element ??!!
   }
}
这样程序肯定是会有bug的,因为erase了iter1的时候,这个指针就无效了,在对它进行任何的操作都会产生问题,可能是一个无法预知的bug或者崩溃。
所以要写成:

for(auto iter1 = theMap.begin(); iter1 != theMap.end(); )
{
    if(iter1->second == xxx)
   {
        theMap.erase(iter1++);  //#1 
   }else
   {
        ++iter1;
   }
} 

好了,其他关于map的用法,查看STL的API,这里只mark一个这样的错误。后续想研究一下map背后的红黑树,当时学数据结构的时候没有学啊~


(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值