求排序后数组中的最大差值

请设计一个复杂度为O(n)的算法,计算一个未排序数组中排序后相邻元素的最大差值。

给定一个整数数组A和数组的大小n,请返回最大差值。保证数组元素个数大于等于2小于等于500。

测试样例:
[9,3,1,10],4
返回:6
由于除了桶排序外任何排序时间复杂最度低也是O(N*log2)所以我们考虑使用桶排序的思想













len 代表数组中数的个数

len个数  len+1个桶去装

最少也要有一个空桶(4个数去装5个桶 咋装满?)

根据以上条件装桶后

任何两个非空桶之间

左边桶最大的值和右边桶最小的值。。。。他们在正常排序后一定也是相邻的(好好体会这句话)

//由于一定会有空桶的存在,所以隔一个空桶之间的差值一定比自己桶内所有数的最大差值要大所以求最大差值我们不考虑桶内的数

//比如 3-4桶 最大值是3  9-10桶最小值是 9        他们中间隔了两个桶(任何情况都会最低有一个空桶存在)他们中间相隔的数就已经大大超过了

//自己桶内可能出现的差值

上代码

import java.util.*;

public class Main {
//	题目:
//	给定一个整形数组arr,返回排序后的相邻两数的最大差值。
//	时间复杂度为O(N)。
	public static void main(String[] args){
		//时间复杂度的限制让我们不可以排序
		//已知任何排序的时间复杂度都可能是O(N)
		//但是我们可以利用桶排序
		//比如有arr.length 9个数 我们给他10个桶
		//用我9个数的最大值和最小值 给他们划分10个等价空间
		int[] arr  = {0,-1,-2,3,-4,5,-6,7,-8};
		int max = MaxGap(arr);
		System.out.println(max);
    }
	
	public static int MaxGap(int[] arr){
		if(arr.length<2||arr==null){
			return 0;
		}
		int len =arr.length;
		int min = Integer.MAX_VALUE;
		int max = Integer.MIN_VALUE;
		//找出最大值和最小值
		for(int i=0;i<len;i++){
			min = Math.min(min,arr[i]);
			max = Math.max(max,arr[i]);
		}
		//如果所有的值都相等
		if(min==max){
			return 0;
		}
		//准备3个动态数组
		//分别,判断空桶、桶中的最小值、桶中最大值
		boolean[] hasNum = new boolean[len+1];
		int[] mins = new int[len+1];
		int[] maxs = new int[len+1];
		//桶的序号
		int bid=0;
		for(int i=0;i<len;i++){
			//计算该数应该放在桶的下标
			bid = bucket(arr[i],len,min,max);
			
			mins[bid] = hasNum[bid]?Math.min(mins[bid],arr[i]):arr[i];
			maxs[bid] = hasNum[bid]?Math.max(maxs[bid],arr[i]):arr[i];
			hasNum[bid]=true;
		}


		
		//之所以用这种差值判断方式是为了防止空桶的存在
		int res= 0;
		int lastMax=maxs[0];
		
		for(int i=1;i<=len;i++){
			if(hasNum[i]){
				res = Math.max(res,mins[i]-lastMax);
				lastMax = maxs[i];
			}
		}
		return res;
	}
	
	//计算该数应该放在桶的下标
	public static int backet(long num,long len,long min,long max){
		return (int)((num-min)*len/(max-min));
	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUNbrightness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值