出现频率前K高的元素

import java.util.*;
class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> m = new LinkedHashMap<>();
        //存入map
        for(int i=0;i<nums.length;i++){
            if(m.containsKey(nums[i])){
                int temp = m.get(nums[i])+1;
                m.put(nums[i],temp);
            }else{
                m.put(nums[i],1);
            }
        }
        List<Map.Entry<Integer,Integer> > l = new ArrayList<>(m.entrySet());
        Collections.sort(l,new Comparator<Map.Entry<Integer,Integer>>(){
            @Override
            public int compare(Map.Entry<Integer,Integer>  o1,
            Map.Entry<Integer,Integer>  o2){
                return o2.getValue()-o1.getValue();

            }
        });

        List<Integer> res = new ArrayList<Integer>();
        for(int i = 0;i<k;i++){
            res.add(l.get(i).getKey());
        }
        return res;
    }
}

题目
在这里插入图片描述

要解决“返回一个非空整数数组中出现频率k元素”的问题,并在频率相同的情况下将这些元素按数值大小排序,可以采用哈希表统计频率、堆结构维护元素以及最终排序的策略。以下是实现思路和关键步骤。 ### 数据结构与算法选择 首先使用哈希表(如 C++ 的 `unordered_map` 或 Python 的 `collections.Counter`)统计每个元素出现的频率,这一步的时间复杂度为 O(n),其中 n 是输入数组的长度[^4]。接着,为了效地找出 k 个元素,可以使用小顶堆来维护当已知的 k 个最元素。每次插入新元素时,如果堆的大小超过 k,则弹出频率最小的元素,这样可以确保堆中始终保留的是当遍历到的 k 个元素。堆操作的总时间复杂度为 O(n log k)[^2]。 最后,从堆中提取元素并进行排序。由于题目要求当频率相同时也要包含所有相同频率元素,并且结果需要按照数值大小排序,因此不能直接输出堆中的内容。而是应该将堆中所有元素取出后,根据频率降序、数值升序进行排序。 ### 示例代码(Python) 以下是一个完整的 Python 实现: ```python from collections import Counter import heapq def top_k_frequent(nums, k): # 统计每个元素频率 count = Counter(nums) # 使用小顶堆维护k个元素 heap = [] for num, freq in count.items(): heapq.heappush(heap, (freq, num)) if len(heap) > k: heapq.heappop(heap) # 提取堆中元素,并按照数值升序排序 result = [num for freq, num in sorted(heap, key=lambda x: (-x[0], x[1]))] return result ``` ### 处理频率相同的元素 在上述实现中,`sorted()` 函数的 `key` 参数设置为 `(lambda x: (-x[0], x[1]))`,表示先按频率降序排列(负号用于降序),再按数值升序排列。这样即使多个元素具有相同的频率,也会被正确排序并包含在最终结果中。 ### 性能分析 - 时间复杂度:O(n log k) 来自堆的操作,加上 O(n) 的频率统计和 O(k log k) 的排序操作,总体为 O(n log k)。 - 空间复杂度:O(n) 用于存储频率表和堆中的元素[^1]。 这种方法能够有效处理大规模数据集,并满足题目对频率相同元素的处理要求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值