最近在做算法题的时候遇到了没有思路的几个题,在这里整理一下:
1.10亿个整数中找到出现次数最多的100个整数。
基本思路:哈希+小顶堆
Hash就是为了统计每个数出现的次数,然后发生冲突的地方用个链表把它链接起来,在每个节点中存储一个含有data和count成员的结构体,data记录相应的数字,而count记录对应的数字出现的次数,这一步的时间复杂度是o(n).(注意这里虽然数字很多,但是因为会存在大量的重复数据,不用担心最后的空间会有10亿)
然后创建一个大小为100的小顶堆,然后将Hash表中前面100个非空的成员放入小顶堆中,然后将hash表中的其他数据和堆顶出现的次数比较,如果比堆顶出现的次数少,则丢弃当前数,如果大于堆顶元素的出现次数,则替换堆顶,然后进行堆调整,这一步时间复杂度是o(nlog100).
2.乱序数组中寻找第K大的数
可以用快速排序的思想来做,假设N个整数存在数字S中,从数组中随机找出一个数X,一趟快速排序之后可以将数组S分成两部分Sa和Sb,其中Sa是小于X的数组部分,Sb是大于X的数组部分,这时有两种情况:
1)Sb中的元素个数小于K,则Sb中的数和Sa中最大的|Sa|-K(|Sa|是Sa中的元素个数)个数是S数组中最大的K个数。所以,第K大个数在Sa数组中,只需要对Sa数组部分进行快速排序,即可找到第K大数(是Sa中的第|Sa|-K大的数)。
2)Sb中的元素个数大于K,则只需要对Sb部分进行排序,位于数组中|Sb|-K位置的数即为整个数组中第K大的数。