Maximum Gap

Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Try to solve it in linear time/space.

Return 0 if the array contains less than 2 elements.

You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.

解法1: 时间O(nlogn), 空间O(1). 排序在比较。

 1 public class Solution {
 2     public int maximumGap(int[] num) {
 3         if(num == null || num.length < 2) return 0;
 4         Arrays.sort(num);
 5         int result = 0;
 6         for(int i = 0; i < num.length - 1; i ++){
 7             result = Math.max(result, num[i + 1] - num[i]);
 8         }
 9         return result;
10     }
11 }

 这一题有两个解法: radix sort 或者 buket sort.

radix sort的话 可以based on 很多形式进行。 如二进制,十进制,或者256.

试着用二进制写了一个:

 1 public class Solution {
 2     public int maximumGap(int[] num) {
 3         if(num == null || num.length < 2) return 0;
 4         radixSort(num);
 5         int max = 0;
 6         for(int i = 1; i < num.length; i ++){
 7             max = Math.max(max, num[i] - num[i - 1]);
 8         }
 9         return max;
10     }
11     
12     private void radixSort(int[] num){
13         if(num == null || num.length == 0) return;
14         int[] ones = new int[num.length];
15         int[] zeros= new int[num.length];
16         int leno = 0, lenz = 0, len = 0;
17         for(int i = 0; i < 32; i ++){//this is an Integer
18             len = 0;
19             lenz = 0;
20             leno = 0;
21             for(int j = 0; j < num.length; j ++){//sort based on current bit position
22                 if(((num[j] >> i) & 1) == 1){
23                     ones[leno++] = num[j];
24                 }else{
25                     zeros[lenz++] = num[j];
26                 }
27             }
28             for(int j = 0; j < lenz; j ++){//put back to num[]
29                 num[len ++] = zeros[j];
30                 zeros[j] = 0;//clean up zero array
31             }
32             for(int j = 0; j < leno; j ++){
33                 num[len ++] = ones[j];
34                 ones[j] = 0;//clean up one array
35             }
36         }
37     }
38 }

如果用bucket sort,那么涉及到一定数学的证明:

官方版(桶排序):

假设有N个元素A到B。

如果有n + 1 个桶,则一定有一个是空的。 且这个桶两边的元素的差一定比同一个桶内元素的差要大。

故要生成一个n + 1 的buckets。

则每一个的间隔是 (max - min) / num.length.

Let Max be the largest number in A and Min be the smallest number in A. Let d = (Max –Min)/(n). We divide all numbers in [MinMax] into n-1 buckets, where k-th bucket contains all numbers in [Min + (k-1)dMin + kd). This can be done by putting element A[i] into the k-th bucket if floor((A[i]-Min)/n) = k. Since there are n-2 numbers that are not equal Min or Max and there are n-1 buckets, at least one of the buckets are empty. That is, any two numbers that are in the same bucket cannot be the answer. Thus, we only need to store the largest number and the smallest number in each bucket. Then, we can scan the buckets sequentially and get a sorted list. The maximum difference between two consecutive elements is the answer.

 1 public class Solution {
 2     class Bucket{
 3         int min;
 4         int max;
 5         public Bucket(){
 6             this.min = Integer.MAX_VALUE;
 7             this.max = Integer.MIN_VALUE;
 8         }
 9     }
10     
11     public int maximumGap(int[] num) {
12         if(num == null || num.length < 2) return 0;
13         int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
14         for(int i = 0; i < num.length; i ++){
15             min = Math.min(min, num[i]);
16             max = Math.max(max, num[i]);
17         }
18         Bucket[] buckets = new Bucket[num.length + 1];
19         for(int i = 0; i < buckets.length; i ++){
20             buckets[i] = new Bucket();
21         }
22         double interval = (double)num.length / (max - min);//put num.length elements into num.length + 1 buckets
23         for(int i = 0; i < num.length; i ++){
24             int pos = (int)((num[i] - min) * interval);
25             if(buckets[pos].min > num[i]) buckets[pos].min = num[i];
26             if(buckets[pos].max < num[i]) buckets[pos].max = num[i];
27         }
28         int result = 0;
29         int pre = buckets[0].max;
30         for(int i = 1; i < buckets.length; i ++){//be care there can be empty buckets
31             if(buckets[i].min != Integer.MAX_VALUE){
32                 result = Math.max(result, buckets[i].min - pre);
33                 pre = buckets[i].max;
34             }
35         }
36         return result;
37     }
38 }