https://leetcode.com/problems/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.
这道题如果直接排序再算的话,复杂度是O(n*lgn),因此,这里用O(n)的排序方法,bucket sort.当一个数列长度是n,最大值是max,最小值是min时,它的最大gap至少为 len = (max-min)/(n-1),因此以这个值为桶的范围,则桶内的元素的差值都应该小于len, 而每个元素进入哪个桶由 (num[i] - min)/len决定。最大差值应该是桶之间存在的最大差值。而不是桶内的差值,因此,当分完桶后,遍历每个桶,就可以算出最大差值了。
public class Solution {
class bucket{
int high;
int low;
public bucket(int high, int low){
this.high = high;
this.low = low;
}
}
public int maximumGap(int[] num) {
if(num==null || num.length<2) return 0;
int max = num[0];
int min = num[0];
for(int i=1; i<num.length; i++){
max = Math.max(max, num[i]);
min = Math.min(min, num[i]);
}
//int len = Math.max((max-min)/(num.length-1), 1);
double interval = (double)(num.length-1)/(max-min);
bucket[] buckets = new bucket[num.length+1];
for(int i=0; i<num.length; i++){
int loc = (int)((num[i]-min)*interval);
if(buckets[loc] == null){
buckets[loc] = new bucket(num[i], num[i]);
}
else{
buckets[loc].high = Math.max(buckets[loc].high, num[i]);
buckets[loc].low = Math.min(buckets[loc].low, num[i]);
}
}
int pre = buckets[0].high;
int maxdif = 0;
for(int i=1; i<=num.length; i++){
if(buckets[i] == null) continue;
else{
maxdif = Math.max(maxdif, buckets[i].low - pre);
pre = buckets[i].high;
}
}
return maxdif;
}
}
以及bucket sort的一些细节问题,待研究。。。。
注意在算interval的时候一定要记得把除数和被除数转化成double后再算,不然interval就是0了。
下面是C++代码:
class bucket{
public:
bucket(int h, int l){
this->high = h;
this->low = l;
}
bucket(){
this->high = -1;
this->low = -1;
}
int high;
int low;
};
class Solution {
public:
int maximumGap(vector<int> &num) {
if(num.size()<2) return 0;
int max = num[0];
int min = num[0];
for(int i=0; i<num.size(); i++){
max = std::max(num[i], max);
min = std::min(num[i], min);
}
double interval = ((double)(num.size()))/((double)(max-min));
bucket buckets[num.size()+1];
int maxdif = 0;
for(int i=0; i<num.size(); i++){
int index = (int)((num[i]-min)*interval);
if(buckets[index].high==-1){
buckets[index].high = num[i];
buckets[index].low = num[i];
}
else{
buckets[index].high = std::max(num[i], buckets[index].high);
buckets[index].low = std::min(num[i], buckets[index].low);
}
}
int pre=buckets[0].high;
for(int i=1; i<=num.size(); i++){
if(buckets[i].high==-1) continue;
else{
maxdif = std::max(maxdif, (buckets[i].low - pre));
pre = buckets[i].high;
}
}
return maxdif;
}
};