美团25春招笔试0412:数组 | 哈希表
【美团】20250412_1_数组1.0
Problem:
给定一个长度为 n 的数组 a。定义一次操作:
选择数组中的一个数,然后把这个数从数组中移除。其余元素按照原有顺序从前到后依次拼接。
现在她想要知道,自己最少需要操作几次,才能使得数组中所有非空子数组的平均值均相同。
子数组为从原数组中,连续的选择一段元素(可以全选、可以不选)得到的新数组。
Solution:
Tag:哈希表
复杂度:时间 O(2*n + Σk) ,最坏退化到 O(2*n^2), 空间 O(n)
思路:其实就是统计一下出现次数最多的数字,然后把其他的数字全部删除,那就平均值一样啦,使用hashmap统计一下次数即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, b;
int ans = -1;
unordered_multiset<int> map;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> b;
map.insert(b);//平均为O(1),最坏是O(n)
}
for (const auto& t : map) {//遍历是O(n)
int temp=map.count(t);//count是O(k)
if (temp > ans) ans = temp;//总时间复杂度为O(n + Σk),最坏情况退化到O(n²)
}
cout << n - ans << endl;
}
optimization:
unordered_multiset 适合需要保留所有重复元素的场景(如统计词频并保留原始顺序)。
unordered_map 适合键值对映射和快速频率统计
这道题更适合使用 unordered_map ,可以将时间复杂度降至 O(n)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, b;
int ans = -1;
unordered_map<int,int> map;//使用unordered_map,可以将时间复杂度降至O(n)
cin >> n;
vector<int> a(n + 1);
for (int i = 0; i < n; i++) {
cin >> b;
map[b]++;
}
for (const auto& t : map) {
if (t.second > ans) ans = t.second;
}
cout << n - ans << endl;
}
Extend:
1.遇到的问题??
for (const auto& t : map) {
if (map.count(t) > ans) ans = map.count(t);
}//一开始是这么写的,但是ans根本不会被赋值,一直是-1
for (const auto& t : map) {
int temp=map.count(t);
if (temp > ans) ans = temp;
}//加了一个中间变量才ok
问了d老师,回答的其实也没看懂
unordered_multiset 允许多个重复元素存在,但遍历时会访问所有重复元素的每个实例。直接调用 count(t) 时:
多次重复计算:当遍历到同一个元素的多个副本时,map.count(t) 会被重复调用多次,虽然返回值相同,但可能因编译器优化或作用域问题导致判断逻辑异常。
条件判断与赋值的分离:在 if (map.count(t) > ans) 和 ans = map.count(t) 中,两次调用 count() 可能被编译器视为独立操作,若中间有其他操作(如容器修改),结果可能不一致。

浙公网安备 33010602011771号