查找热点数据问题
问题描述
给你一个整数数组 nums 和一个整数 k,请你用一个字符串返回其中出现频率前 k 高的元素。请按升序排列。
你所设计算法的时间复杂度必须优于 O(n log n),其中 n 是数组大小。
输入
- nums: 一个正整数数组
- k: 一个整数
返回
返回一个包含 k 个元素的字符串,数字元素之间用逗号分隔。数字元素按升序排列,表示出现频率最高的 k 个元素。
参数限制
- 1 <= nums[i] <= 10^4
- 1 <= nums.length <= 10^5
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 给定一个nums数组:int nums[ ],一个整数:k,输出一串字符串。
速成3天python但是算法仍写不习惯,故我写了第一个cpp算法后转译为python,pass~
代码思路(c++):
#include <iostream>
#include <queue>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
// 定义一个结构体来存储整数和它的频率
struct NumFreq {
int num;
int freq;
NumFreq(int n, int f) : num(n), freq(f) {}
};
// 定义比较器,用于优先队列
struct Compare {
bool operator()(const NumFreq& a, const NumFreq& b) const {
if (a.freq == b.freq) {
return a.num > b.num; // 频率相同,按整数大小升序
}
return a.freq > b.freq; // 按频率升序
}
};
int main() {
int nums[100], n, k;
cout << "Enter the number of elements (n): ";
cin >> n;
cout << "Enter the elements: ";
for (int i = 0; i < n; ++i) {
cin >> nums[i];
}
cout << "Enter the value of k: ";
cin >> k;
// 使用哈希表统计每个整数的频率
unordered_map<int, int> freqMap;
for (int i = 0; i < n; ++i) {
freqMap[nums[i]]++;
}
// 使用优先队列(最小堆)来存储频率和整数
priority_queue<NumFreq, vector<NumFreq>, Compare> pq;
// 将频率和整数加入优先队列
for (const auto& entry : freqMap) {
pq.push(NumFreq(entry.first, entry.second));
}
// 输出前k个整数
cout << "The top " << k << " elements by frequency are: ";
for (int i = 0; i < k; ++i) {
if (pq.empty()) break;
cout << pq.top().num << " ";
pq.pop();
}
cout << endl;
return 0;
}
算法和时间复杂度分析:
- 使用了最小堆(这里使用c++标准库中的queue中的priority_queue类)对自定义节点的插入和删除算法时间复杂度为O(log2 n);
- 使用了无序哈希表unordered_map容器,用哈希表来计数。
- 关于优先队列具体的实现逻辑,我使用了一个比较器compare
priority_queue<NumFreq, vector<NumFreq>, Compare> pq
第一个参数NumFreq为结构体类型;第二个参数为装载若干结构体的容器,注意这里要引入头文件vector ,compare也是用结构体定义,用来重载运算符‘>’来实现pq内部排序逻辑。
个人心得:
个人感觉MarsCode最好用的一个地方就是在给定题目较长的时候可以通过思路提示,代码提示来先对题目形成一个大概认知,分析测试用例和输出,这一部分的思考得到AI助手的提示,然后把更多的思考和精力放在算法实现和优化的具体逻辑上面,对于想要高效刷题的小白和友友们还是不错滴~
建议:可以让AI帮你写基本思框架,具体代码实现自己上手,又不会用的数据结构和算法可以直接问MarsCode,还是建议多自己思考,可以先自己分析题目,写好重要过程的注释,然后和AI回答作对比,对比一下有哪些地方是自己疏漏的,然后慢慢总结~
最后附上python代码
代码思路(python):
def solution(nums, k):
# 统计每个元素的频率
frequency = {}
for num in nums:
if num in frequency:
frequency[num] += 1
else:
frequency[num] = 1
# 按频率排序
sorted_elements = sorted(frequency.items(), key=lambda item: item[1], reverse=True)
# 选择前 k 个频率最高的元素
top_k_elements = sorted_elements[:k]
# 按升序排列
top_k_elements.sort(key=lambda item: item[0])
# 返回结果
result = ','.join(str(item[0]) for item in top_k_elements)
return result
if __name__ == "__main__":
# You can add more test cases here
print(solution([1, 1, 1, 2, 2, 3], 2) == "1,2")
print(solution([1], 1) == "1")