博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序17:相邻两数最大差值
阅读量:3728 次
发布时间:2019-05-22

本文共 2620 字,大约阅读时间需要 8 分钟。

题目:有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。测试样例:[1,2,5,4,6],5返回:2

思路:直接的思路,先排序,再遍历数组求出相邻2个数的差,保留最大值即可,此时时间复杂度为O(nlogn)。本题采用的是桶排序的思想,对于n个数,设置n+1个桶,具体的,先遍历数组找出min和max,差值区间设置为d=(max-min)/n,于是区间是[min~min+d);[min+d~min+2d)……[min+(n-1)d~min+nd)这n区间,再单独为最大值max设置一个桶,于是得到n+1个桶,已知数组元素总共有n个,但是桶有n+1个,并且元素min必定在第一个桶中,max必定在n+1号桶中;显然要把n个元素放入到n+1个桶中必定会产生空桶,已知数组中的元素时整数,而虽然每个桶区间不一定是整数,例如[23/7,31/7),但是没有关系,对于任意一个元素,它总会落入到某一个桶中,并且可以知道,不同桶之间元素的差值必定大于d,同一个桶中的元素的差值必定小于d,于是可知要求元素之间的最大差值只需要在不同的桶之间寻找,不用在同一个桶中寻找,并且题目要求是排序后相邻2个元素的最大差值,于是应该寻找2个相邻非空桶中前一个桶的最大值与后一个桶的最小值之间的差值,遍历所有桶,比较得到所有差值中的最大值就是结果所要求的相邻2数最大差值。注意理解:最终要对每2个非空的相邻的桶求差值,而不能根据空桶的数目来确定2个相邻桶的差值,因为桶的长度可能是小数,那么间隔2个空桶和间隔3个空桶并不意味着后者具有更大的差值,因此应该对所有相邻的非空桶根据前桶的最大值和后桶的最小值求出差值作为比较对象,因此在遍历时对于每一个桶,要求出这个桶中元素的最大值maxOfBucket[i],最小值minOfBucket[i],并且保留上一个非空桶的maxOfLastBucket,于是差值着2个相邻非空桶的差值就是result= minOfBucket[i]- maxOfLastBucket;然后将当前桶的maxOfBucket[i]最为下一个桶的maxOfLastBucket。逐步替换result,当遍历完成时就可以得到最大差值。

具体的解决方式:

①已知应该设置的桶的数目是n+1,建立一个数组boolean[] hasNumber=new blloean[n+1];用来表示每个桶i中是否存在元素;如果没有元素就是空桶,可以直接跳过。

②设置数组maxOfBucket[],minOfBucket[]用来记录每个桶中元素的最大值和最小值,设置变量maxOfLastBucket用来表示上一个非空桶的最大值。

③创建方法private int getBucketIndex(int number,intlength,int max,int min)根据一个数组的长度,最大值最小值,已知数据number,计算number这个数会被散列到的桶的下标。

④先将数组中的所有元素散列到桶中,更新所在桶的hasNumber[i]、maxOfBucket[i]、minOfBucket[i]的值;

然后从i=0的桶开始遍历桶,先找到第一个非空的桶,将其最大值作为下一个元素的maxOfLastBucket,然后往下遍历,跳过空的桶,遇到非空的桶,就计算result= minOfBucket[i]- maxOfLastBucket,并且与已有的result比较,保留最大值,直到遍历结束返回结果result即可。

import java.util.*;//这道题目的思路很棒,巧妙而灵活:利用桶排序的思想散列数组,求最大差值就是求2个相邻非空桶的最大差值public class Gap {    public int maxGap(int[] A, int n) {        //特殊输入:如果只有一个元素,显然最大差值为0        if(A==null||A.length<2) return 0;                //创建n+1个桶,hasNumber[]表示该桶是否有元素        boolean[] hasNumber=new boolean[A.length+1];        //每个桶中可以有多个数,记录每个桶的最大值和最小值        int[] maxOfBucket=new int[A.length+1];        int[] minOfBucket=new int[A.length+1];        //记录上一个桶的最大值        int maxOfLastBucket=0;                //进行散列,把数组中的元素散入桶,注意不要搞混桶的下标和元素的下标,这里研究的都是桶的下标        for(int i=0;i
maxOfBucket[bucketIndex]? A[i]:maxOfBucket[bucketIndex]; minOfBucket[bucketIndex]=A[i]
result? (minOfBucket[i]-maxOfLastBucket):result; //将当前桶的最大值作为下一个桶的maxOfLastBucket maxOfLastBucket=maxOfBucket[i]; } } return result; } //已知一个数组A,并且已知将其分成n+1个桶,给定A[i],求出应该落入的桶的下标 private int getIndexOfBucket(int[] array,int i){ //求出数组array的最大、最小值 int max=array[0]; int min=array[0]; for(int j=1;j
max? array[j]:max; min=array[j]

你可能感兴趣的文章
bugku 文件包含2
查看>>
bugku 求getshell
查看>>
各种绕过
查看>>
bugku 细心
查看>>
BugKu -- 程序员本地网站
查看>>
bugku杂项
查看>>
GET_and_POST
查看>>
xss的简单的理解
查看>>
git的基本使用
查看>>
linux学习资料
查看>>
linux终端输入命令时常用的快捷键
查看>>
requests库的简单使用
查看>>
sql注入总结
查看>>
windows下提权的辅助工具
查看>>
python脚本借助代理刷浏览量
查看>>
浅谈csrf和ssrf
查看>>
ubuntu提示E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用)
查看>>
TCP/IP的基本理解
查看>>
PHP无字母数字构造Webshell
查看>>
JWT与cookie和token的区别
查看>>