利用桶进行排序

给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度0(N),且要求不能用非基于比较的排序。

求解:

利用桶。  ①准备N个数,准备N+1个桶。

      ②遍历数组找最小值min和最大值max

      1.如果min=max,数组是一种数,差值为0;

      2.如果min!=max:

        则①最小值放在0号桶,最大值放在第N号桶,中间数值等分为N+1份放入中间的桶中。

        ****中间必有一个空桶。

        排序后的相邻数:1.在一个桶(内部差值一定是不需要的)

                2.不在一个桶(最大差值来自不同的桶,前提是桶内不止一个数(除了例子a))

例子a:

    左边是非空桶有max  中间是空桶  右边是非空桶min   (空桶左右非空桶)

      max与min的差值大于桶表示的范围

      ①找非空桶的前一个非空桶的最大值,记录相减差

      ②为什么不直接找空桶?

        当空桶前后的非空桶只进入一个数值后:

          A(10-19)   B(20-29)    C(39-39)    D(40-49)

            19       null        30        49

          这种情况下,AC相差11,CD相差19.所以不直接找空桶。

 

代码如下:

  1 public static int maxGap(int [] nums) {
  2             
  3             if(nums==null||nums.length<2) {
  4                 return 0;    
  5             }
  6             
  7             int len =nums.length;//数组长度
  8             int min =Integer.MAX_VALUE;//系统最大值做数组中的最小值
  9             int max=Integer.MIN_VALUE;//系统最小值做数组中的最大值     目的遍历找到最小值最大值
 10             
 11             for(int i=0;i<len;i++) {
 12                 min=Math.min(min, nums[i]);
 13                 max=Math.max(max, nums[i]);
 14             }
 15             //更新最值
 16             if(min==max) {
 17                 return 0;
 18             }
 19             //长度都位N+1
 20             //每个桶的三组信息
 21             boolean[] hasNum=new boolean[len+1];
 22             int [] maxs=new int[len+1];
 23             int [] mins=new int[len+1];
 24             int bid =0;
 25             
 26             for(int i=0;i<len;i++) {//重新遍历整个数组
 27                 //确定当签署属于几号桶
 28                 bid=bucket(nums[i],len,min,max);
 29                 //数组放入桶中后,比较更新最值
 30                 mins[bid]=hasNum[bid]?Math.min(mins[bid], nums[i]):nums[i];
 31                 maxs[bid]=hasNum[bid]?Math.max(maxs[bid], nums[i]):nums[i];
 32                 //更新信息
 33                 hasNum[bid]=true;
 34             }
 35             
 36             int res=0;
 37             int lastMax=maxs[0];
 38             int i=1;
 39             //找到每一个非空桶和左边最近的非空桶
 40             for(;i<len;i++) {
 41                 //用当前最小值——前一个桶的最大值
 42                 if(hasNum[i]){
 43                     //差值;
 44                     res=Math.max(res, mins[i]-lastMax);
 45                     lastMax=maxs[i];
 46                 }
 47             }
 48             //返回差值
 49             return res;
 50         }
 51         
 52         public static int bucket(long num, long len, long min, long max) {//num  数值,len  桶的个数
 53             // TODO 自动生成的方法存根
 54             //确定来自哪个桶
 55             return (int) ((num-min)*len/(max-min));
 56         }
 57         
 58         /*
 59         //对数器测试
 60         public static int comparator(int[] nums) {
 61             if(nums ==null||nums.length<2) {
 62                 return 0;
 63             }
 64             
 65             Arrays.sort(nums);//系统内置排序
 66             int gap=Integer.MIN_VALUE;
 67             for(int i=1;i<nums.length;i++) {
 68                 gap=Math.max(nums[i]-nums[i-1], gap);
 69             }
 70             return gap;
 71         }
 72         
 73         //随机生成数组
 74         public static int[] generatateArray(int maxSize,int maxValue) {
 75             int[] arr=new int[(int) ((maxSize+1)*Math.random())];
 76             for(int i=0;i<arr.length;i++) {
 77                 arr[i]=(int)((maxValue+1)*Math.random())-(int)(maxValue*Math.random());
 78                 return arr;
 79             }
 80             
 81             //复制主数组
 82             
 83             
 84             public static void main(String[] args) {
 85                 int testTime=50000;
 86                 int maxsize=100;
 87                 int maxvalue=100;
 88                 boolean succeed=true;
 89                 
 90                 for(int i=0;i<testTime;i++) {
 91                     int [] arr1=generatateArray(maxSize,maxValue);
 92                     int [] arr2=copyArray(arr1);
 93                     
 94                     if(maxGap(arr1)!=comparator(arr2)) {
 95                         succeed=false;
 96                         break;
 97                     }
 98                 }
 99                 System.out.println(succeed?"ok!":"No");
100             }
101         }
102 
103         private static int[] copyArray(int[] arr) {
104             // TODO 自动生成的方法存根
105                 if (arr == null) {
106                     return null;
107                 }
108                 int[] res = new int[arr.length];
109                 for (int i = 0; i < arr.length; i++) {
110                     res[i] = arr[i];
111                 }
112                 return res;
113             }
114             */
115         public static void main(String[] args) {
116             int a[] = {23,45,2,78,6,88,9,10,24};
117             maxGap(a);
118             System.out.println(maxGap(a));
119         }

 

 

  

        

        

posted on 2019-02-26 10:08  Edit-s  阅读(97)  评论(0编辑  收藏  举报

导航