leetcode 164. 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)的时间复杂度下求出经排序后的相邻两数的最大差
例如 6 1 5 8
排序后变成1 5 6 8
三个差值: 4 1 2
此时Maximum Gap取4
尝试使用DP的方式解决但是没能成功,后来看了答案了解到了桶排序Bucket sort这一神奇的O(n)排序算法
算法简介:
先遍历数组,找到最大值和最小值
将数组平均分割为n个木桶.每个木桶容量为(maxnum-minnum)/(size-1)
例如 1 2 3三个数
可分为 [1,2) [2,3) [3,4)三个木桶,遍历一遍数组即可把全部元素插入到对应的桶中,插入的同时更新该桶桶中数据的最大值与最小值
最后遍历一遍所有木桶,max(后一个木桶的最小值减去前一个装有数字的木桶的最大值) 即为所要求的结果
(因为如果每个桶中都被填充了数字,那么此次排序相当于进行了一次精确的排序,那么此方法可以求出结果;
如果出现一个桶中出现不止一个数字,那么必定至少有一个桶是空出来的,此方法求出来的数字必定大于一个木桶的容积,所以不用考虑桶内数字的gap情况)
代码:
class Solution { public: int maximumGap(vector<int> &num) { int sSize = num.size(); int i, res =0; int minV, maxV; int bucket_size, bucket_num, bucket_id; int maxGap = INT_MIN; int last_max; if(sSize>1) { minV = maxV = num[0]; for(i=1; i<sSize; i++) { if(minV > num[i]) minV = num[i]; else if(maxV < num[i]) maxV = num[i]; } bucket_size = max(1, (maxV - minV )/ (sSize - 1))); bucket_num = (maxV - minV)/bucket_size + 1; if(bucket_num <=1) return (maxV - minV); vector<int> bucket_max(bucket_num, INT_MIN); vector<int> bucket_min(bucket_num, INT_MAX); vector<int> bucket_count(bucket_num, 0); for(i=0; i<sSize; i++) { bucket_id = (num[i] - minV)/bucket_size; bucket_count[bucket_id]++; bucket_min[bucket_id] = bucket_min[bucket_id] > num[i]? num[i]:bucket_min[bucket_id]; bucket_max[bucket_id] = bucket_max[bucket_id] < num[i]? num[i]:bucket_max[bucket_id]; } last_max = minV; for(i=0; i<bucket_num; i++) { if(bucket_count[i]>0) { maxGap = max(maxGap, bucket_min[i]- last_max); last_max = bucket_max[i]; } } return maxGap; } return 0; } };
在实际应用中对海量数据进行排序处理时可以使用桶排序,通过扩大木桶的数量,牺牲内存(即减少每个桶的长度范围),可以使排序变得更精确
浙公网安备 33010602011771号