NO.69 查找热点数据问题
问题描述
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按任意顺序返回答案。
- 1 <= nums.length <=
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
你所设计算法的时间复杂度必须优于 O(n log n) ,其中 n 是数组大小。
示例 1
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2
输入: nums = [1], k = 1
输出: [1]
测试案例分析
以 nums = {4,4,4,2,2,2,3,3,1}, k = 3 为例:
- 出现频率依次为
{数字,频数}: {4, 3}, {2, 3}, {3, 2}, {1, 1}。 - 取频率前 k 高的元素,即
4, 2, 3。 - 有序排列:
[2,3,4]。
最终返回值为 "2,3,4"。
题目解析
- 首先,我们需要构建一个 vector<pair<int,int>>arr 用于存储初始 nums 中的数字和对应的频数
- 然后,我们需要根据频数对 arr 中的 pair 进行降序排序,以便找到其中出现频率前 k 高的元素
- 接着,我们需要取出出现频率前 k 高的元素存入 vector<int>result
- 另外,我们需要对 result 中的元素按照数字大小升序排序
- 最后,我们对 result 中的元素按照题目所需的格式返回 string
定义变量如下:
- 记录 nums 中的数字和对应的频数:vector<pair<int,int>>arr
- 记录某数字出现的频数:count
- 记录目前所在索引位置:pos
- 记录前 k 个高频元素的集合:vector<int> result
代码实现
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
std::string solution(std::vector<int> nums, int k) {
sort(nums.begin(),nums.end());
vector<pair<int,int>>arr(nums.size());
int count=0;
int pos=0;
for(int i=0;i<nums.size();i++){
if(i==0 || nums[i]==nums[i-1]){
count++;
}
else {
arr[pos] = make_pair(nums[i-1], count);
count=1; //此时与上一索引对应数组的值不同,个数重新初始化,且为1
pos++;
}
}arr[pos] = make_pair(nums.back(), count); //处理最后一个元素
sort(arr.begin(), arr.end(), [](pair<int, int>& a, pair<int, int>& b) {
return a.second > b.second; // 按频率降序
});
vector<int> result;
for (int i = 0; i < k; i++) { //取出前k个元素
result.push_back(arr[i].first);
}
sort(result.begin(),result.end()); //对返回结果按照升序排序
string rst;
for(int j=0;j<k;j++){ //匹配题目所需返回格式
rst.push_back('0'+result[j]);
if(j!=k-1) rst.push_back(',');
}
return rst;
}
注意:
- 初始化时,使用 sort 对 nums 进行排序,能避免在 arr 中还需对乱序的数字输入进行处理,有效降低了时间复杂度
- 在遍历 nums 并更新 arr 后,count 需重置,由于此时处在与前元素不同的第一个数的位置,所以
count = 1 - 在遍历 nums 并记录 count 时,对于最后一个元素需要单独处理,否则会漏掉最后一个元素的记录
- 对 arr 根据频数进行降序排列使用 sort 方法:
sort(arr.begin(), arr.end(), [](pair<int, int>& a, pair<int, int>& b) { return a.second > b.second; }); - 题目测试案例要求对最终输出按照元素数字大小升序排序,故需要对 result 进行
sort(result.begin(),result.end())的额外处理 - 本解法的时间复杂度为 O(nlogn)