LeetCode#164最大间距
题目链接
题意非常简单,给你一个无序的数组,让你对数组排序之后找到最大的相邻数之差。我啪的一下很快啊就敲了一个用sort排序,然后再遍历一遍数组得到了答案(
很明显这并不是正解,官方题解给出的答案是使用基数排序,那就记录一下如何进行基数排序吧。
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。(百度百科)
举个简单的例子:使用基数排序对73, 22, 93, 43, 55, 14, 28, 65, 39, 81进行排序:
比如我们可以使用10个桶,先对它们的个位进行排序:
1 2 3 4 5 6 7 8 9 10
| 0: 1:81 2:22 3:73 93 43 4:14 5:55 6: 7: 8:28 9:39
|
然后是按照十位进行排序:
1 2 3 4 5 6 7 8 9 10
| 0: 1:14 2:22 28 3:39 4:43 5:55 6:65 7:73 8:81 9:93
|
将两次排序的结果进行合并,我们就能得到结果了:14 22 28 39 43 55 65 73 81 93
如果数组中有三位数乃至n位数,我们只需要继续进行排序,直到全部位置都遍历完。
回到这个题,我们使用基数排序就可以这样写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Solution { public: int maximumGap(vector<int>& nums) { int n = nums.size(); if (n < 2) { return 0; } int exp = 1; vector<int> buf(n); int maxVal = *max_element(nums.begin(), nums.end());
while (maxVal >= exp) { vector<int> cnt(10); for (int i = 0; i < n; i++) { int digit = (nums[i] / exp) % 10; cnt[digit]++; } for (int i = 1; i < 10; i++) { cnt[i] += cnt[i - 1]; } for (int i = n - 1; i >= 0; i--) { int digit = (nums[i] / exp) % 10; buf[cnt[digit] - 1] = nums[i]; cnt[digit]--; } copy(buf.begin(), buf.end(), nums.begin()); exp *= 10; }
int ret = 0; for (int i = 1; i < n; i++) { ret = max(ret, nums[i] - nums[i - 1]); } return ret; } };
|
(使用基数排序结果反而比用sort慢。。。。果然人家写好的现成的就是比自己写的强啊