題目如下:
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.
分析如下:
考慮了很多方法,估計要用到bucket sort或者radix sort。後來放狗一搜發現果然要用到bucket sort.
基本思路是這樣的,把n個數放到x個桶中。我們可以構造一個合適的x,並且通過下面的證明發現,max gap只可能出現在兩個桶之間,不能出現在一個桶的內部。
下面是證明,直接抄官方的解答:
Suppose there are N elements and they range from A to B.
Then the maximum gap will be no smaller than ceiling[(B - A) / (N - 1)]
Let the length of a bucket to be len = ceiling[(B - A) / (N - 1)], then we will have at most num = (B - A) / len + 1 of bucket
for any number K in the array, we can easily find out which bucket it belongs by calculating loc = (K - A) / len and therefore maintain the maximum and minimum elements in each bucket.
Since the maximum difference between elements in the same buckets will be at most len - 1, so the final answer will not be taken from two elements in the same buckets.
For each non-empty buckets p, find the next non-empty buckets q, then q.min - p.max could be the potential answer to the question. Return the maximum of all those values.
My Code:
//48msstruct Bucket { int local_min; int local_max; int local_volumn; Bucket():local_volumn(0){};};class Solution {public: int maximumGap(vector<int> &num) { if (num.size() < 2) return 0; if (num.size() == 2) return num[0] - num[1] > 0 ? num[0] - num[1] : num[1] - num[0]; int min = INT_MAX; int max = INT_MIN; int max_gap = 0; for (int i = 0; i < num.size(); ++i) { if (num[i] < min) min = num[i]; if (num[i] > max) max = num[i]; } int bucket_length = (max - min) / (num.size() - 1) + 1; //maximum gap >= ceiling[(B - A) / (N - 1)]// int bucket_length = (max - min) / num.size() + 1; //居然也能AC...... int bucket_count = (max - min) / bucket_length + 1; vector<Bucket> bucket(bucket_count, Bucket()); for (int i = 0; i < num.size(); ++i) { int index = (num[i] - min) / bucket_length; if (bucket[index].local_volumn == 0) //NOTE1: 如果桶內最多隻有一個元素,那麼max 和 min都賦值為這個元素。 bucket[index].local_max = bucket[index].local_min = num[i]; else if (num[i] > bucket[index].local_max) bucket[index].local_max = num[i]; else if (num[i] < bucket[index].local_min) bucket[index].local_min = num[i]; bucket[index].local_volumn++; } int previous = 0; //NOTE2: 用previous來跳過空桶,第0個桶必然不是空桶,所以previous可以從0開始取值。 for (int i = 1; i < bucket.size(); ++i) { if (bucket[i].local_volumn == 0) continue; if (bucket[i].local_min - bucket[previous].local_max > max_gap) max_gap = bucket[i].local_min - bucket[previous].local_max; previous = i; } return max_gap; }};
小結擴充:
1 排序的基本思想可以擴充出很多內容。
2 經過測試發現
bucket_length = (max - min) / (num.size() - 1) + 1;
如果寫為
bucket_length = (max - min) / num.size() + 1;
也可以AC。
但是從意義上來說,第1種寫法我覺得才是正確的。第2種暫時還沒有想到反例去推翻,但是Then the maximum gap will be no smaller than ceiling[(B - A) / (N - 1)], 所以從意義上來說我覺得不正確。
3 題目中說32-bit,我覺得強烈暗示了可以用bit方式進行radix sort,這個思路還沒實現。