[LeetCode] 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) 时间复杂度,O(n)空间复杂度

解题思路:

思路一:将所有数组全部排序,再一次遍历求得最大的相邻元素间隔值即可。但是排序算法的最小时间复杂度也需要 O(n*logn) ,无法满足要求。

思路二:题目只需要求出最大相邻间隔,可以利用桶排序,避免求出全部元素大小顺序,而得到结果。时间复杂度降低为 O(n)。

具体思路:

  • 将元素全部减去最小值,得到新的数组
  • 根据数组长度,创建同样大小的桶(数组表示),并根据数组的数值区间、数组长度得到单个桶的大小
  •   double bucketSize = (double)(maxv-minv) / (double)nums.size();
  • 根据元素大小,将元素放到对应的桶里面。数组中最大值,最小值应该分别在最左边、最右边的两个桶里面。
  •   int idx = newNums[i] / bucketSize;
  •   bucket[idx].push_back(newNums[i]);

// 断言 : 最大间隔值为桶间间隔的最大值。

// 断言证明:当每个桶都有值时,每个桶只有一个值,断言成立。当至少有一个桶为空时,因为最左边、最右边两个桶都有值,则最大间隔必然为桶间间隔,而不是桶内间隔,断言成立。

  • 去掉每个桶中最大值、最小值之外的其他值
  • 一次遍历求得最大桶间间隔,即为原题解。

 

 1     int maximumGap(vector<int>& nums) {
 2         
 3         if (nums.size() < 2) {
 4             return 0;
 5         }
 6         
 7         int maxv = nums[0];
 8         int minv = nums[0];
 9         for (int i = 0 ; i < nums.size(); i++) {
10             maxv = max(maxv, nums[i]);
11             minv = min(minv, nums[i]);
12         }
13     
14         vector<int> newNums;
15         for (int i = 0 ; i < nums.size(); i++) {
16             newNums.push_back(nums[i] - minv);
17         }
18         
19         vector<vector<int>> bucket(nums.size() + 1);
20         
21         double bucketSize = (double)(maxv-minv) / (double)nums.size();
22         
23         // maxv == minv 
24         if (bucketSize == 0 ) {
25             return 0;
26         }
27                 
28         for (int i = 0 ; i < newNums.size(); i++) {
29             int idx = newNums[i] / bucketSize;
30             bucket[idx].push_back(newNums[i]);
31         }
32     
33         for (int i = 0 ; i < bucket.size(); i++) {
34             if (bucket[i].size() >= 2) {
35                 int maxi = bucket[i][0];
36                 int mini = bucket[i][0];
37                 for (int k = 0 ; k < bucket[i].size(); k++ ) {
38                     maxi = max(maxi, bucket[i][k]);
39                     mini = min(mini, bucket[i][k]);
40                 }
41                 bucket[i] = {mini, maxi};
42             }
43         }
44         
45         int maxgap = 0;
46         
47         int lmaxi = (bucket[0].size() == 1) ?    bucket[0][0] : bucket[0][1];
48         
49         for (int i = 0 ; i < bucket.size(); i++) {
50             if (bucket[i].size() == 0 ) {
51                 continue;
52             }
53             int maxi;
54             int mini;
55             
56             if (bucket[i].size() == 1) {
57                 maxi = bucket[i][0];
58                 mini = bucket[i][0];
59             }else{
60                 // size of bucket[i] shoud be 2;
61                 
62                 mini = bucket[i][0];
63                 maxi = bucket[i][1];
64             }
65             
66             if ((mini - lmaxi) > maxgap) {
67                 maxgap = (mini - lmaxi);
68             }
69             lmaxi = maxi;
70         }
71                 
72         return maxgap;
73     }

 

posted @ 2016-01-10 01:16  TonyYPZhang  阅读(417)  评论(0编辑  收藏  举报