腾讯2017暑期实习生笔试题(有趣数字)

本文解析了一道腾讯实习生招聘笔试题,题目要求从一组数中找出差值最大和最小的二元组数量。文章详细介绍了作者的解题思路,包括数组排序、计算最大差值和最小差值的二元组数量等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   之前准备把腾讯实习生招聘的第三道题做出来的,但是时间很紧,最终拖到今天才完成的,下午做了一个小时才弄出来的,主要是细节方面的问题。



这个题意思很简单吧,给出很多数,找出“二元组”里面差最小的和差最大的个数(两个数的差事大的减去小的,也就是绝对值的意思)。说实话,这个题的处理确实很难把握。

    我的解题思路是:先将这个数组排序,然后就很容易计算出差最大的二元组的个数,接下来就是计算最小二元组的个数。

  • 最大二元组的计算是分别计算出最大值和最小值(可能存在重复,需要把握住),假设最小值的个数为n,最大值的个数为m,那么差最大的二元组的个数即为:n*m,若是不明白
  
 
  • 最小二元组的计算则相对复杂一些,但是排序以后,最小差距的计算就是计算相邻两个数的差。其中需要把握的东西就是计算过程中”差距“由一个值变为另一个值的时候需要好好把握,这个时候很容易出错。我按照我写的代码来讲述,大家可以根据我所说的自己再设计代码,主要是一些细节的变化。还需要注意的一点就是,最小差并不一定是连续的,可能会间隔一些,我给个例子,大家对照着看看吧。

我写的代码会刚开始的时候跳过对开始部分的两个4的统计,最小值跟给出的值总是想差一点点,最后发现问题是出在两次最小差改变的时候,下面给出代码,供参考一下。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void Solution(vector<int>& V){
	int sz = V.size();
	int min = 0;
	int minNum = 0;//最小二元组数目
	int maxNum = 0;//最大二元组数目
	if (sz == 0){
		cout << 0 << " " << 0 << endl; //差最小,差最大
		return;
	}
	else if (sz == 1){
		cout << 1 << " " << 1 << endl;
	}
	else{
		sort(V.begin(), V.end()); //排序

		int i = 0;
		int j = sz - 1;

		while (V[i] == V[i + 1] && i < sz - 1){
			++i;
		}
		while (V[j] == V[j - 1] && j > 0){
			--j;
		}
		maxNum = (i + 1)*(sz - j); //差最大的数

		min = V[sz - 1] - V[0] + 1;
		int flag = 0;
		for (int k = 0; k < sz - 1; ++k)
		{
			if (V[k + 1] - V[k] < min){
				min = V[k + 1] - V[k];
				minNum = 1;
				flag = 1; //主要用于记录差距第一次变为0
				if (min == 0)
				{
					--k; //这样做的目的是为了不错过min=0的,第一次统计的时候会少统计一个
				}
			}
			else if (V[k + 1] - V[k] == min){
				int sum = 0;
				while (k< sz -1 && V[k + 1] - V[k] == min)
				{
					++k;
					++sum;
				}

				if (min == 0){	//差距为0				
					if (flag == 1){
						minNum = (sum)*(sum + 1) / 2; //差距一次变为0的时候需要好好注意
						flag = 0;
					}
					else{
						minNum += sum*(sum + 1) / 2;//根据相同元素个数计算二元组个数
					}
				}
				else{ //差距不为0
					minNum += sum;
					--k;  //k会加两次(for循环也会加一次,所以需要调整一下)
				}
			}
		}
	}
	cout << minNum << " " << maxNum << endl;
}

int main()
{
	int n;
	int tmp;
	while (cin >> n){
		vector<int> arr;
		for (int i = 0; i< n; ++i){
			cin >> tmp;
			arr.push_back(tmp);
		}
		Solution(arr);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值