55.Top K Frequent Elements(出现次数最多的k个元素)

本文介绍了一种高效算法,用于从整数数组中找出出现频率最高的前K个元素。通过使用哈希表统计频次,并结合桶排序思想,实现优于O(nlogn)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Level:

  Medium

题目描述:

Given a non-empty array of integers, return the k most frequent elements.

Example 1:

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example 2:

Input: nums = [1], k = 1
Output: [1]

Note:

  • You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
  • Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
思路分析:

  step1.显然,为了找出数组中出现频次最多的前k个元素,首先,我们需要分别统计出数组中各个元素出现的频次,很容易想到哈希表,Java中提供了HashMap类,它实现了Map接口,HashMap是一个泛型类(HashMap<key,value>),可以用来存储键/值对,为了统计数组个元素的频次,我们可以把元素数值作为“键”,对应元素出现的次数作为“值”,如此,我们只需要对数组进行一次遍历就可以得到一张包含不同数组元素和对应出现频次的“映射表”。

  step2.由于我们关心的是出现频次最多的前k个元素,因此,得到频次统计“映射表”之后,我们需要根据频次对映射表中的键/值对进行排序。

  step3. 映射表中键(数据元素)和值(该数据元素出现的频次)是一一对应的,我们在按值进行排序的同时需要记录其对应的元素,鉴于此,我们可以采用“桶排序”的思想。由于我们是按数据元素出现的频次进行排序的,那么“桶”的数量范围是可以确定的——桶的数量小于等于给定数组元素的个数。编号为i的桶用于存放数组中出现频次为i的元素——即编号为i的桶存放“映射表”中“值”等于i的“键”。

   step4. 排序完成后,编号大的桶中元素出现的频次高,因此,我们“逆序”(先取桶编号大的桶的元素)获取桶中数据,直到获取数据的个数等于k,我们将当前桶的元素取尽(同一个桶中元素出现的频次相等),然后停止取数据,完成!

代码:
public class Solution{
    public List<Integer>topKFrequent(int []nums,int k){
        List<Integer>res=new ArrayList<>();
        if(k>nums.length||nums==null)
            return res;
        HashMap<Integer,Integer>map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        List<Integer>[]bucket=new ArrayList[nums.length+1]; //构造桶
        for(int key:map.keySet()){ //按照键值进行遍历
            int count=map.get(key);
            if(bucket[count]==null){ //以桶的下标作为出现的次数
                bucket[count]=new ArrayList<>();
            }
            bucket[count].add(key);
        }
        for(int i=nums.length;i>=1;i--){
            if(bucket[i]!=null&&res.size()<k){ //取k个最频繁的数。
                res.addAll(bucket[i]);
            }
        }
        return res;
    }
}

转载于:https://www.cnblogs.com/yjxyy/p/11089343.html

### 实现方法 为了找到整数数组中频率最高的元素,可以按照以下方式编写 C 语言程序。此过程涉及遍历数组并记录每个元素出现的次数,最后找出具有最高频次的那个元素。 ```c #include <stdio.h> #define MAX_SIZE 100 // 定义最大数组大小 // 函数用于查找频率最高的元素及其出现次数 void findMaxFrequency(int arr[], int n, int *maxFreqElement, int *frequency) { int count[MAX_SIZE] = {0}; // 初始化计数器数组 // 遍历输入数组来填充count[] for (int i = 0; i < n; ++i){ if(arr[i] >= 0 && arr[i] < MAX_SIZE) count[arr[i]]++; } *maxFreqElement = 0; *frequency = count[0]; // 查找最大的频率以及对应的元素 for (int j = 1; j < MAX_SIZE; ++j){ if(count[j] > *frequency){ *frequency = count[j]; *maxFreqElement = j; } } } int main() { int array[] = {1, 3, 2, 4, 3, 2, 3, -1, 7, 8, 8, 8}; int size = sizeof(array)/sizeof(array[0]); int maxFreqElement, frequency; findMaxFrequency(array, size, &maxFreqElement, &frequency); printf("The most frequent element is %d which appears %d times.\n", maxFreqElement, frequency); return 0; } ``` 上述代码定义了一个`findMaxFrequency()`函数,该函数接受一个整数数组作为参数,并返回两个值——最常出现的元素(`*maxFreqElement`)和它的出现次数(`*frequency`)。注意这里假设所有的整数值都在合理的范围内(即小于预设的最大尺寸),并且只考虑非负整数的情况[^1]。 对于更复杂的数据集或不同的需求,可能需要调整这段代码以适应特定的应用场景,比如处理更大的范围内的整数或是包括负数在内的所有整数等情形。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值