题目:
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.
Credits:
Special thanks to @porker2008 for adding this problem and creating all test cases.
基本思路,linear time / space, bucked sort。
Maximum Gap >= ceil [(maxValue - minValue) / (N - 1)] > ceil [(maxValue - minValue) / (N - 1)] - 1 = Maximum difference if we choose bucket size as: ceil [(maxValue - minValue) / (N - 1)]. 所以如果选择bucket_size = ceil [(maxValue - minValue) / (N - 1)],我们可以保证Maximum Gap一定不在同一个Bucket里。那么Maximum Gap一定是后一个非空桶的最小值减去前一个非空桶的最大值,然后取这些相邻桶间差值的最大值。
三个核心变量:
Bucket_size = ceil [(maxValue - minValue) / (N - 1)]
Bucket_num = (maxValue - minValue) / Bucket_size + 1
index = (num[i] - minValue) / Bucket_size
桶里只需要存该桶的最小值和最大值即可。
C++版:
class Solution { public: int maximumGap(vector<int>& nums) { if(nums.size() < 2) return 0; int max = 0, min = INT_MAX; for(auto i: nums) { max = i > max ? i : max; min = i < min ? i : min; } int bucket_size = (max - min) / (nums.size() - 1) + 1; int bucket_num = (max - min) / bucket_size + 1; vector<vector<int>> buckets(bucket_num); for(auto i: nums) { int index = (i - min) / bucket_size; if(buckets[index].empty()) { buckets[index].push_back(i); buckets[index].push_back(i); } else { buckets[index][0] = i < buckets[index][0] ? i : buckets[index][0]; buckets[index][1] = i > buckets[index][1] ? i : buckets[index][1]; } } int prev = 0; int maxGap = 0; if(buckets.size() == 1) return buckets[0][1] - buckets[0][0]; for(int i = 0; i < buckets.size(); i++) { if(buckets[i].empty()) continue; prev = i; int j; for(j = i + 1; j < buckets.size(); j++) if(!buckets[j].empty()) break; if(j < buckets.size() && buckets[j][0] - buckets[prev][1] > maxGap) { maxGap = buckets[j][0] - buckets[prev][1]; prev = i; i = j - 1; } } return maxGap; } };
public class Solution { public int maximumGap(int[] num) { if(num.length < 2) return 0; int max = num[0], min = num[0]; for(int i = 1; i < num.length; i++) { if(num[i] > max) max = num[i]; if(num[i] < min) min = num[i]; } int bucket_size = (max - min) / (num.length - 1) + 1; int bucket_num = (max - min) / bucket_size + 1; List<List<Integer>> buckets = new ArrayList<>(); for(int i = 0; i < bucket_num; i++) { List<Integer> temp = new ArrayList<>(); buckets.add(temp); } for(int i = 0; i < num.length; i++) { int index = (num[i] - min) / bucket_size; if(buckets.get(index).isEmpty()) { buckets.get(index).add(num[i]); buckets.get(index).add(num[i]); } else { if(buckets.get(index).get(0) > num[i]) buckets.get(index).set(0, num[i]); if(buckets.get(index).get(1) < num[i]) buckets.get(index).set(1, num[i]); } } int maxGap = 0; if(buckets.size() == 1) { return buckets.get(0).get(1) - buckets.get(0).get(0); } int prev = 0; for(int i = 0; i < buckets.size() - 1; i++) { if(buckets.get(i).isEmpty()) continue; prev = i; int j; for(j = i + 1; j < buckets.size(); j++) if(!buckets.get(j).isEmpty()) break; if(j < buckets.size() && buckets.get(j).get(0) - buckets.get(i).get(1) > maxGap) { maxGap = buckets.get(j).get(0) - buckets.get(i).get(1); prev = j; i = j - 1; } } return maxGap; } }
class Solution: # @param {integer[]} nums # @return {integer} def maximumGap(self, nums): if len(nums) < 2: return 0 maxValue = max(nums) minValue = min(nums) bucket_size = int((maxValue - minValue) / (len(nums) - 1)) + 1 bucket_num = int((maxValue - minValue) / bucket_size )+ 1 buckets = [None] * bucket_num for i in nums: index = int((i - minValue) / bucket_size) if buckets[index] == None: buckets[index] = {'min':i, 'max':i} else: if i < buckets[index]['min']: buckets[index]['min'] = i if i > buckets[index]['max']: buckets[index]['max'] = i maxGap = 0 if bucket_num == 1: return buckets[0]['max'] - buckets[0]['min'] for i in range(bucket_num): if buckets[i] == None: continue j = i + 1 while j < bucket_num and buckets[j] == None: j += 1 if j < bucket_num and buckets[j]['min'] - buckets[i]['max'] > maxGap: maxGap = buckets[j]['min'] - buckets[i]['max'] i = j return maxGap