最大差值

题目描述

  给定一个未排序的数列,找到此数列在已排序状态下的两个相邻值的最大差值,少于两个值时返回0。例如:给定数列 [1,3,2,0,1,6,8] 则 最大差值为3。注意:请尽量使用时间复杂度为O(n)的方案。

输入描述

  第一行输入单个整数N作为数列的大小,第二行输入所有数列中的元素M,共N个。0 < N <= 1000000, 0 < M < 2100000000。

输出描述

数列的最大差值

解题思路

  这道题使用二分排序后AC了,但是题目要求使用时间复杂度O(N),而一般的排序算法很难达到这个时间复杂度(可以使用桶排序)。之所以使用O(n)的时间复杂度就可以解决这道题,是因为我们不需要通过严格的数据位置信息。
  这里的思路是n个数,找出最小minv和maxv,将其划分为n个区间,其中maxv单独一个区间,前面n-1个区间每个区间大小是delta=(maxv-minv)/(n-1),这样就形成了[a,a+delta)形式的区间,而所有相邻数据的差值最大值就是两个区间间的差值(下一个区间的最小值和上一个区间的最大值的差值)最大值,区间内的相邻数的差值是不需要考虑的,原因在于这N个数,第一个数和最后一个数分别放在第一个区间和最后一个区间内,中间的数如果存在有多个数在同一个区间的情况,那么一定至少存在一个区间i内没有数,这样区间i+1和i-1的差值一定大于delta,如果所有的数都单独在一个区间内,那么就直接比较所有区间的差值,因此无论如何我们都不需要考虑区间内相邻数的差值情况。

实现代码

#include <iostream>
#define NN 2100000000
#include <vector>
using namespace std;
int main(){
	int n,i,maxv,minv;
	cin>>n;
	vector<int> data(n,0);
	maxv=0,minv=NN;
	for(i=0;i<n;i++){
		cin>>data[i];
		if(maxv<data[i]) maxv=data[i];
		if(minv>data[i]) minv=data[i];
	}
	int delta=(maxv-minv)/(n-1);
	if(n==2||delta==0) {
	cout<<0<<endl;
	return 0;
	}
	vector<int> bucketMin(n,NN),bucketMax(n,0); 
	for(i=0;i<n;i++){
		int index=(data[i]-minv)/delta;
		if(bucketMin[index]>data[i]) bucketMin[index]=data[i];
		if(bucketMax[index]<data[i]) bucketMax[index]=data[i];
	}
	int last_max=bucketMax[0];
	int max_delta=0;
	for(i=1;i<n;i++){
		if(bucketMin[i]!=NN&&bucketMin[i]-last_max>max_delta)
			max_delta=bucketMin[i]-last_max;
		if(bucketMax[i]!=0)
			last_max=bucketMax[i];
	}
	cout<<max_delta<<endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值