您的位置:首页 > 其它

排序相关—— 相邻两数的最大差值( Maximum Gap-LeetCode)

2017-07-18 21:11 417 查看
题目链接:https://leetcode.com/problems/maximum-gap/#/description

参考答案:http://www.programcreek.com/2014/03/leetcode-maximum-gap-java/

给定一个整型数组arr,返回如果排序之后,相邻两数的最大差值。例如:某数组排序之后为 1 2 3 4 7 8 9,最大差值来自于4和7,所以返回3.

最优解时间复杂度为O(N),额外空间复杂度为O(N).

这道题的思想是桶排序,但不是真正的桶排序。

思路:

1.找出数组的最大值和最小值

2.把最大值和最小值上的数[min,max)等量地分成n个区间,n为数组个数;每个区间分别对应一个桶,每个数根据各自的区间选择进入的桶,把最大值单独放在n+1号桶中。

3.因为桶的数量有n+1个,而数组的个数只有n个,因此必然存在空桶。同一个桶中数的差值肯定不会大于桶区间,而来自空桶两侧的差值必然大于桶区间。所以不用考虑一个桶中的相邻数,只需要考虑来自两个桶的相邻数的差值,即后一个桶的最小值和前一个桶的最大值。

4.接下来只需要考虑每个桶的最小值和上一个桶中的最大值自己的差值,并且记录他们的最大差值,即为结果。

public class FindMaxDivision {

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums={7,9,3,4,2,1,8};
System.out.println(findMaxDivision(nums));
}

public static int findMaxDivision(int[] nums){
if(nums==null || nums.length<2)
return 0;

//找出数组的最大值和最小值
int max=nums[0];
int min=nums[0];
for(int i=1;i<nums.length;i++){
if(nums[i]<min){
min=nums[i];
}
if(nums[i]>max){
max=nums[i];
}
}
if(max==min)
return 0;
int[] minA=new int[nums.length+1]; //存放每个桶中的最小值,最后一个桶刚好用来放最大值
int[] maxA=new int[nums.length+1]; //存放每个桶中的最大值
for (int i=0; i<nums.length+1; ++i) {
minA[i] = -1;
maxA[i] = -1;
}
double interval=(double)nums.length/(max-min);
for(int i=0;i<nums.length;i++){   //注意i的范围,不是nums.length+1,会越界
int tag=(int)((nums[i]-min)*interval);
if(minA[tag]==-1){
minA[tag]=nums[i];
maxA[tag]=nums[i];
}else{
minA[tag]=Math.min(minA[tag],nums[i]);
maxA[tag]=Math.max(maxA[tag],nums[i]);
}
}

///找出第一个空桶的前一个桶的最大值和最后一个空桶的后一个桶的最小值

int result=0;
int prev=maxA[0];
for(int i=1;i<nums.length+1;i++){
if(minA[i]!=-1){
result=Math.max(result,minA[i]-prev);
prev=maxA[i];
}
}
return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: