美团 2020 年实习生招聘笔试题——最好一样

最好一样

题目描述

时间限制:C/C++语言 1000MS;其他语言 3000MS

内存限制:C/C++语言 131072KB;其他语言 655360KB

题目描述: 给出一个序列包含 n 个正整数的序列 A,然后给出一个正整数 x,你可以对序列进行任意次操作的,每次操作你可以选择序列中的一个数字,让其与 x 做按位或运算。你的目的是让这个序列中的众数出现的次数最多。

请问众数最多出现多少次。

输入

输入第一行仅包含两个正整数 n 和 x,表示给出的序列的长度和给定的正整数。(1<=n<=100000,1<=x<=1000)

接下来一行有 n 个正整数,即这个序列,中间用空格隔开。(1<=a_i<=1000)

输出

输出仅包含一个正整数,表示众数最多出现的次数。

样例输入

5 2
3 1 3 2 5

样例输出

3

提示

样例解释

例如如果序列中所有数字都不修改时,众数为 3,3 出现的次数为 2,如果我们把1 都做如题操作,序列会变为 3,3,3,2,5,此时众数为 3,出现次数为 3,所以我们选择后者方案,输出众数出现的次数,即 3。

解题思路

这道题看起来有点绕,但是想清楚之后就知道可以分为两步解决这个问题:

  • 首先将x与序列的所有数做一次或运算(这样众数个数才是最多的)
  • 求新序列的众数出现的次数

代码如下:

#include<iostream>
#include<algorithm>
#include<unordered_map>

using namespace std;

int getNum(int a[], int n)
{
	unordered_map<int, int> myMap;
	int MaxNum = 0;
	for(int i = 0; i < n; i ++)
	{
		myMap[a[i]] ++;
	}
	for(auto i = myMap.begin(); i != myMap.end(); i ++)
	{
		if(i -> second > MaxNum)
		{
			MaxNum = i -> second;
		}
	}
	return MaxNum;
}
 
int main()
{
	int n, x;
	int a[100000];
	cin >> n >> x;
	for(int i = 0; i < n; i ++)
	{
		cin >> a[i];
	}
	for(int i = 0; i < n; i ++)
	{
		a[i] = a[i] | x;
	}
	cout << getNum(a, n);
	return 0;
}

求数组中众数及其出现次数的方法有很多,我之前习惯用一个新数组的索引表示原数组的值,用新数组的值表示对应索引的数字在原数组中出现的次数,但是这种方式存在明显的缺点:

  • 大量数组空间空闲
  • 新数组的长度受制于原数组中的最大值
  • 当原数组中存在负数时该方法失效

推荐使用哈希表的键值对来储存原数组中的数字及其出现的次数,C++11中的unordered_map可以很好的胜任众数相关的问题。

发布了47 篇原创文章 · 获赞 73 · 访问量 3817

猜你喜欢

转载自blog.csdn.net/whuhewei/article/details/104940063