zoukankan      html  css  js  c++  java
  • 利用桶进行排序

    给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度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         }

      

            

            

  • 相关阅读:
    安利一个_Java学习笔记总结
    九涯的第一次
    attrs 资源文件 自定义属性
    EditText
    ArrayList 数组 初始化方法
    HTTP Retrofit 网络传输
    画布Canvas 画笔Paint
    View控件跟随鼠标移动
    ViewPager和Fragment中的View的点击事件冲突
    圆形图片 ImageView
  • 原文地址:https://www.cnblogs.com/Vsxy/p/10435554.html
Copyright © 2011-2022 走看看