美团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() 可能被编译器视为独立操作,若中间有其他操作(如容器修改),结果可能不一致。
posted @ 2025-04-15 17:24  Sylvia_lee  阅读(35)  评论(0)    收藏  举报