C++实现数组中出现最频繁的前top k个元素

要求: 时间复杂度小于等于 nlogn.

算法解题思路:

1, 由于原始数组是杂乱无序的, 所以 统计数组中元素出现的次数时间复杂度达到了n^2, 不符合题意.

2, 在统计数组中的元素出现次数之前, 先对数组进行排序, 用时间复杂度是 nlogn的排序算法进行排序,  在这里用C++ 中函数库STL中的sort直接排序, 关于STL中sort实现(成熟的快速排序算法, 结合了内插排序,具体读读STL中实现).

3. 从排好序的第一个元素开始扫描,  统计每个元素出现的次数,时间复杂度为n.

4. 由3给出的每个元素的统计情况,  与2类似的方法进行从大到小排序,  取出前K个对应元素即可,时间复杂度nlogn.

附源代码:

#include<vector>
#include<algorithm>
#include<cstdlib>
#include<iostream>
using namespace std;

/*this  practice C++  knowledge:
vector  : useage,     memory management, iterator
algorithm:sort(), user identify function
cstdlib: creating random number
*/
struct key_value{
     int key;
     int num;
};

bool compare(const key_value& k1, const key_value& k2) {
        return k1.num>k2.num;
}
class Solution {
    public:
        vector<int> topKFrequent(vector<int>& nums, int k) {
            int j=0;
            int number=1;
            int num=nums.size();
            vector<key_value> topk;
            vector<int>* key=new  vector<int>(0);//very important
            sort(nums.begin(),nums.end());//原始数组排序
            for(int i=1;i<num;i++){
                if(nums[i]==nums[j]){
                    number++;
                }
                else{
                    key_value kv;
                    kv.key=nums[j];
                    kv.num=number;
                    topk.push_back(kv);
                    number=1;
                    j=i;
                }
            }//统计元素的频数
            key_value kv;
            kv.key=nums[j];
            kv.num=number;
            topk.push_back(kv);//统计最后一个元素
            sort(topk.begin(),topk.end(), compare);
            j=1;
            for(vector<key_value>::iterator it=topk.begin();it!=topk.end()&&(j<=k);it++){
              key->push_back((*it).key);
              j++;
            }//前K个元素取出来
            return (*key);
        }

};
int main(){
    Solution sl;
    vector<int>::iterator it;
    vector<int> v;
    for(int i=0;i<10;i++)
           v.push_back(rand()%10+1);
    vector<int> topk=sl.topKFrequent(v,2);//取出数组中出现次数最频繁的前K个元素.,这里是2
    for(it=topk.begin();it!=topk.end();it++)
      cout<<(*it)<<" , ";
    cout<<endl;
    return 0;
}

时间: 2024-10-30 02:01:30

C++实现数组中出现最频繁的前top k个元素的相关文章

给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

1 """ 2 #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 3 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 4 解题思路: 5 1.设定一个空字典,去存储列表中的值和值出现的次数 6 2.使用L.count()方法可以统计出L中值出现的次数 7 3.使用sorted方法可以进行排序,sorted(iterable,key,reverse) 8 注意key是函数 9 4.列表中的元祖取值 d[i][j] i是哪一个元祖,j是元祖

C语言:对传入sp的字符进行统计,三组两个相连字母“ea”&quot;ou&quot;&quot;iu&quot;出现的次数,并将统计结果存入ct所指的数组中。-在数组中找出最小值,并与第一个元素交换位置。

//对传入sp的字符进行统计,三组两个相连字母“ea”"ou""iu"出现的次数,并将统计结果存入ct所指的数组中. 1 #include <stdio.h> 2 #include <string.h> 3 #pragma warning (disable:4996) 4 void fun(char*sp ,int *ct) 5 { 6 int a=0, b=0, c=0; 7 while (*sp != '\0') 8 { 9 if (*s

python_exercise_给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

# 设定给出的非空数组为list_a,如下list_a = [8,1,3,5,1,2,45,8,5,7,7,8,8,8,8,8,8,5,5] # 将list_a去重,留下唯一值list_a_set = set(list_a) # 将list_a去重后的值作为字典的key放到字典中list_a_dict = {x:None for x in list_a_set} # 遍历将list_a去重后的唯一值,统计唯一值出现的次数.把次数作为字典的value放到字典中for l in list_a_set

31.向数组中插入一个元素

import java.util.*; public class Insert { public static void main(String[] args) { int[] list = new int[6]; // 长度为为6的数组 list[0] = 99; list[1] = 85; list[2] = 82; list[3] = 63; list[4] = 60; int index = list.length; // 保存新增成绩插入位置 System.out.println("请

哈希(6) - 判断数组中是否存在重复元素且距离在K之内

给定一个包含多个重复元素的未排序的数组.另外给定一个数字k,且k小于数组大小.判断数组中是否包含重复元素,且它们相隔的距离处于范围k之内. 例如: Input: k = 3, arr[] = {1, 2, 3, 4, 1, 2, 3, 4} Output: false 所有重复元素的距离>k. Input: k = 3, arr[] = {1, 2, 3, 1, 4, 5} Output: true 存在重复元素1,且距离为3(==k). Input: k = 3, arr[] = {1, 2,

一个整数数组中最大字数组二

返回整数数组中最大子数组的和2 1.题目: 返回一个整数数组中最大子数组的和. 2.要求: 1)要求程序必须能处理1000个元素: 2)每个元素都是int32类型的. 3.设计思路: 处理1000个元素时让用户自己输入想要的数组长度,看看运行时出处理时间的长短,再在源程序中改善这一问题. 处理大数溢出时,由于随机函数生成的数不算太大,我们尽量让其最终存入数组的元素接近最大范围,进而求和时才可能出现大数溢出的情况. 4.源代码: 1 #include<iostream> 2 #include&l

算法之找出数组中出现次数大于n/m的元素

最经典的题目莫过于是: 在一个数组中找出出现次数超过n/2的元素?更进一步的,找出数组中出现次数大于n/3的所有元素? 注:这里有一个很重要的事实,那就是出现次数大于n/m的元素的个数至多为(m-1)个,比如出现次数大于n/3的至多只有两个. 关于这一类题目的解题思路,可以先讲一个游戏 称作 "俄罗斯方块".这里的规则是每一行的元素要完全不一样,一样的元素则总是在同一列,如果最下面的行已经被填满,那么消除最下面的行. 例如在数组 A = {7,3,3,7,4,3,4,7,3,4,3,4

LintCode- 删除排序数组中的重复数字

题目描述: 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 样例 给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2]. 1 public class Solution { 2 /** 3 * @param A: a array of integers 4 * @return : return an integer 5 */ 6 public int removeD

删除排序数组中的重复数字、买卖股票的最佳时机、爬楼梯

题目1:删除排序数组中的重复数字 描述:给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 题目2:买卖股票的最佳时机 描述:假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 题目3:爬楼梯 描述:假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶